I am having an array which consist of 3 data which I need to insert in pouchdb, so I'm using a for loop to insert the data, but the problem is it is not inserting complete data because the loop finishes before callback.
for(var i=0;i<data.length;i++){
var jsondoc=doc1;//document
console.log(i) //getting console for all data. eg:1,2,3
console.log(data[i])//getting console for all data. eg:hi, hello
jsondoc.messages.push({msg: data[i]}); //updating message, here need to be done somthing
db.put(jsondoc, function(err2, response2){
if (err2) { console.log(JSON.stringify(err2)); }
console.log("this is not repeating") ;
});
}
Since the db insertion runs async, you cannot put the loop on hold until the operation completes. One thing that you can do is to serialise the db inserts with a helper function like this:
function insertItem(data, i, completeCallback) {
// check if we still have items to send
if(i < data.length) {
var jsondoc=doc1;//document
//updating message, here need to be done somthing
jsondoc.messages.push({msg: data[i]});
db.put(jsondoc, function(err2, response2){
if (err2) {
console.log(JSON.stringify(err2));
}
// recursively call to push the next message
insertItem(data, i+1, completeCallback);
});
} else {
// no more items to send, execute the callback
if(typeof completeCallback === "function") {
completeCallback();
}
}
}
You'll have to update your code so that instead of continuing the execution after the call of the function, to pass that code into the callback of the pushMessage function, so if your original code looks like this:
// ... code before the loop
for(var i=0;i<data.length;i++){
// ... original body of the loop
}
// ... code to execute after the loop and that currently causes problems
you'll need to change it like this:
// ... original code that was before the loop
insertItem(data, 0, function() {
// ... original code hat was executed after the loop and that caused problems
// but now it gets executed after all items were inserted in db
}
Another alternative would be to send all inserts in parallel and perform a join() on those operations; you'll still need the callback workaround though. Something along the lines:
function insertItems(data, callback) {
var remainingItems = data.length;
if(remainingItems === 0 && typeof callback === "function") {
callback();
}
for(var i=0;i<data.length;i++){
var jsondoc=doc1;//document
console.log(i) //getting console for all data. eg:1,2,3
console.log(data[i])//getting console for all data. eg:hi, hello
jsondoc.messages.push({msg: data[i]}); //updating message, here need to be done somthing
db.put(jsondoc, function(err2, response2){
if (err2) { console.log(JSON.stringify(err2)); }
remainingItems--;
if(remainingItems === 0 && typeof callback === "function") {
// I know, code redundancy :P
callback();
}
});
}
}
The usage of this second function is the same as for insertItem.
If I understand you correctly, your problem is a scoping issue. jsondoc or data[i], or whichever variable is causing the problem, is changed before your callback can complete.
Take a look at this jsFiddle, which shows how to solve such a scoping problem.
for(var i = 0; i < 3; i++){
(function(){
var j = i;
setTimeout(function(){
callback(j)
}, 500);
})();
}
If you look at your js console when the jsFiddle runs you'll see that the first loop prints 3 times 3, which is the finishing value for i. While the second, where we store the value to a new variable inside a new scope, outputs 1, 2, 3 as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With