Cannot read property 'unsubscribe' of undefined - firebase

i have a ionic project.
I want to unsubscribe when i get the cities from subscription of firebase return.
But something goes wrong and it throws following error when i try to unsubscribe.
How can is solve that?
My code.
getCities() {
let i: any;
let a = this.firebaseProvider.getOtoparks()
.subscribe(data => {
for (i = 0; i < data.length; i++) {
this.cities.push({
name: data[i]['details']['sehir'],
value: i,
}
);
}
// try to unsubscribe
a.unsubscribe();
});
}

The best practice is to use take(1) when you want to unsubscribe without a condition.
getCities() {
let i: any;
let a = this.firebaseProvider.getOtoparks()
.take(1)
.subscribe(data => {
for (i = 0; i < data.length; i++) {
this.cities.push({
name: data[i]['details']['sehir'],
value: i,
});
}
});
}

Related

Can't see my results in Ionic3 with SqLite, even though it recognizes number of rows

there, I'm new to Ionic and trying to learn my way with SQLite in it.
I get success in creating and droping tables, and after using INSERT INTO in a table I try to read its contents... That's when things get weird: I get a response like this:
{"rows":{"length":5},"rowsAffected":0}
Here's the code:
let sqlait: SQLite = new SQLite();
return sqlait.create({
name: 'contacomigo.db',
location: 'default'
}).then(
(db: SQLiteObject) => {
return db.executeSql('SELECT ' + Conta.col_id + ' FROM ' + Conta.tabela, {})
.then((data) => {
d.alert(JSON.stringify(data));
for (let i = 0; i < data.rows.length; i++) {
contas.push(data.rows.item(i));
}
})
.catch(e => d.alert(e));
}
).catch(e => { d.alert(e) });
if (contas.length == 0) {
contas.push('0 contas!');
} else {
d.alert(JSON.stringify(contas))
}
return contas.toString();
}
I would really love to learn that it's something ridiculous that I'm missing... Thanks in advance!
You have to fetch the results like this.
for (var i = 0; i < data[0].rows.length; i++) {
}

Puppeteer / Node - Target.createTarget - Target Closed

I'm using Node/Puppeteer in the code below, passing in a large list of URL's for traversal and scraping. It has been difficult to do it asynchronously, though I find that I am getting closer and closer to the answer. I am currently stuck on an issue related to the following error.
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 17): Error: Protocol error (Target.createTarget): Target closed.
This error occurs once upon every iteration of the while loop. Though I'm not sure what I may be doing incorrectly.
Could someone help me do the following:
1) Diagnose the source of the error.
2) Potentially find a more effective way to traverse a large list of URLs asynchronously.
async function subProc(list, batchSize) {
let subList = null;
let i = 0;
while (list.length > 0) {
let browser = await puppeteer.launch();
subList = list.splice(0, batchSize);
console.log("Master List Size :: " + list.length);
console.log("SubList Size :: " + subList.length);
for (let j = 0; j < subList.length; j++) {
promiseArray.push(new Promise((resolve, reject) => {
resolve(pageScrape(subList[j], browser));
}));
}
Promise.all(promiseArray)
.then(response => {
procArray.concat(response);
});
promiseArray = new Array();
try {
await browser.close();
} catch(ex){
console.log(ex);
}
};
}
async function pageScrape(url, browser) {
let page = await browser.newPage();
await page.goto(url, {
timeout: 0
});
await page.waitFor(1000);
return await page.evaluate(() => {
let appTitle = document.querySelector('').innerText;
let companyName = document.querySelector('').innerText;
let dateListed = document.evaluate("", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerText;
let category = document.evaluate("']//a//strong", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerText;
/* */
return {
appTitle,
companyName,
dateListed,
category
}
}).then(response => {
let urlData = {
id: subList[j],
appName: response.appTitle,
companyName: response.companyName,
dateListed: response.dateListed,
category: response.category
}
return urlData;
});
};
I figured out the solution to the problem I was having.
Every computer is limited in its processing ability, so instead of iterating through 1000 urls simultaneously you have to break it down into smaller pieces.
By using a PromiseAll, and iterating and scraping 10 urls at a time and storing these values in an array, I was able to throttle the processing required to iterate through all 1000 urls.
processBatch(subData, 10, procArray).then((processed)=>{
for(let i = 0; i < procArray.length; i++){
for(let j = 0; j < procArray[i].length; j++){
results.push(procArray[i][j]);
}
}
function processBatch(masterList, batchSize, procArray){
return Promise.all(masterList.splice(0, batchSize).map(async url =>
{
return singleScrape(url)
})).then((results) => {
if (masterList.length < batchSize) {
console.log('done');
procArray.push(results);
return procArray;
} else {
console.log('MasterList Size :: ' + masterList.length);
procArray.push(results);
return processBatch(masterList, batchSize, procArray);
}
})
}

How to set results retried from sqlite db table to array in react native?

Here is my code
var employeeList = [] ;
let db = SQLite.openDatabase({name: 'test.db', createFromLocation : "~example.db", location: 'Library'}, false,false);
db.transaction((tx) => {
tx.executeSql('SELECT * FROM Employees', [], (tx, results) => {
console.log("Query completed");
var len = results.rows.length;
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
employeeList.push(row.name);
}
this.setState({employees:employeeList});
db.closeDatabase();
});
});
alert(this.state.employees);
I am able to set result to employeeList inside a transaction.But When I am checking employeeList outside the transaction,it is getting blank...
What I have to do to set results.row to employees object..
It's asynchronous. You're asking for a value before the DB transaction has been performed. You need to use promises or callbacks to know when the query has executed.
As Gabriel mentioned, you need to wrap the call in a Promise. I provided an example of how you might want to do it.
const getEmployees = new Promise(function(resolve, reject) {
var employeeList = [] ;
let db = SQLite.openDatabase({name: 'test.db', createFromLocation : "~example.db", location: 'Library'}, false,false);
db.transaction((tx) => {
tx.executeSql('SELECT * FROM Employees', [], (tx, results) => {
console.log("Query completed");
var len = results.rows.length;
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
employeeList.push(row.name);
}
db.closeDatabase();
// resolve promise
resolve(employeeList)
});
});
getEmployees.then(data => {
this.setState({
employees:employeeList
})
})

Issue wit for loop and promise... for loop not waiting for reponse of getRoleName function. how to do this?

for loop not waiting for reponse of getRoleName function.
how to do this?Issue with for loop and promise.
for(var i = 0; i < data.rows.length; i++) {
alert("inside" + i);
this.getRoleName(data.rows.item(i).role_id).then((data1)=>{
this.users.push({
id: data.rows.item(i).id,
text: data.rows.item(i).username,
role: data1.rows.item(i).role_text
});
},(error)=>{
});
}
getRoleName(id):Promise<any> {
let text : String;
let sql = "select role_text from roles where id = "+id;
return this.db.executeSql(sql, {}).then((data) => {
return data;
},(error) => { alert("i im in eerror");
console.error("Unable to execute sql", JSON.stringify(error));
});
}

Firebase Queue - Handling Reject/Resolve while Looping

I have a Queue that looks like this
new Queue(queueRef, options, ({post, user, postId}, progress, resolve, reject) => {
rootRef.child(`users/${user.user_id}/followers`).once('value', (snapshot) => {
const followers = toArray(snapshot.val())
for (var i = 0; i < followers.length; i++) {
rootRef.child(`users/${followers[i].user_id}/feed/${postId}`).set(post, (err) => {
if (err) {
reject(err)
} else if (i >= followers.length - 1) {
resolve({post, user, postId})
}
})
}
}, reject)
})
My issue is that I'm really only resolving once all the sets have finished and rejecting if any of those fail. What I'd like to do is somehow pass each iteration of a loop to another Queue which can then reject/resolve for that specific request rather than the whole collection.
This looks like it's probably an XY problem and probably has a better solution. But you're looking for something like Q.all().
In essence, call a method that does each op and returns a promise, and resolve/reject when the entire set is done.
new Queue(queueRef, options, ({post, user, postId}, progress, resolve, reject) => {
rootRef.child(`users/${user.user_id}/followers`).once('value', (snapshot) => {
var promiseList = [], p;
const followers = toArray(snapshot.val())
for (var i = 0; i < followers.length; i++) {
p = processNextFollower(followers[i]);
// p.then(progress);
promiseList.push(p);
}
Q.all(promiseList).then(resolve, reject);
}, reject)
})
function processNextFollower(follower, postId) {
var def = Q.defer();
rootRef.child(`users/${follower.user_id}/feed/${postId}`).set(post, (err) => {
if (err) {
def.reject(err)
} else if (i >= followers.length - 1) {
def.resolve({post, user, postId})
}
})
}
return def.promise;
}

Resources