Ludwig Loth
Ludwig Loth

Reputation: 57

Update more than one document in a loop

Background:

I use PouchDB (indexedDB) for an offline NW.js App and I'm new to no-sql. I also use the PouchDB plugin Upsert, this basiclly does an db.get() and db.put() in the background.

Problem:
I dynamically create n documents and in another function i want to update them all with the upsert function in a loop, but i have to return the document that I want to update. So the loop stops at the first run(logically, just normal behavior).

Is there a way to update n documents with one function in a loop?

Here's my code example:

var temp = $('#number_discuss_points').val();

for (i = 1; i < temp; i++) {
    var v1= $('#discusspoint_heading' + i).val();
    var v2= $('#discusspoint_subheading' + i).val();
    var v3= $('#point_number' + i).val();
    var v4= $('#dpoint_deadline' + i).val();
    var v5= $('#responsible_person' + i).val();
    var v6= $('#dp_text' + i).val();  

    db.upsert(id_body + i, function (sheet) {
        sheet._id = id_body + i;
        sheet.discusspoint_heading = v1;
        sheet.discusspoint_subheading = v2;
        sheet.point_number = v3;
        sheet.dpoint_deadline = v4;
        sheet.responsible_person = v5;
        sheet.dp_text = v6;

        return sheet; //Logically, the functions stops here and return everthing with 1

    }).then(function (result) {
        console.log(result);
    }).catch(function (err) {
        console.log(err);
    });
}

Upvotes: 0

Views: 265

Answers (2)

Megidd
Megidd

Reputation: 7938

First create an array of docs inside a for loop:

docArray=[]

for(i=1;i<10;i++){
    /* Create doc */
    doc={}
    doc._id=i
    doc.whatever='The Power of '+ i
    /* Push doc to array */
    docArray.push(doc)
}

Now, reduce the docArray to a chained promise:

docArray.reduce((seq,doc)=>{
    return seq.then(()=>{
        /*Chain "db.pusert" promise to seq*/
        return db.upsert(doc._id,function(docOLD){return doc})
    });
},Promise.resolve()/* Initial value of seq */)
.then(res=>{console.log('All "db.upserts" resolved')})
.catch(err=>{throw new Error(err)})

Upvotes: 1

IanC
IanC

Reputation: 883

I think Nolan Lawson will be along shortly with a much better answer than me, but here goes anyway... in your loop you can add each returned promise from db.upsert into an array. After the loop, you can use Promise.all to process all the promises like this:

var temp = $('#number_discuss_points').val();

var promise_list = [];

for (i = 1; i < temp; i++) {
    var v1= $('#discusspoint_heading' + i).val();
    var v2= $('#discusspoint_subheading' + i).val();
    var v3= $('#point_number' + i).val();
    var v4= $('#dpoint_deadline' + i).val();
    var v5= $('#responsible_person' + i).val();
    var v6= $('#dp_text' + i).val();  

    promise_list.push(db.upsert(id_body + i, function (sheet) {
        sheet._id = id_body + i;
        sheet.discusspoint_heading = v1;
        sheet.discusspoint_subheading = v2;
        sheet.point_number = v3;
        sheet.dpoint_deadline = v4;
        sheet.responsible_person = v5;
        sheet.dp_text = v6;

        return sheet; //Logically, the functions stops here and return everthing with 1
    }));
}

Promise.all(promise_list).then(function (result_list) {
    for(var result in result_list) {
        console.log(result);
    }
    }).catch(function (err) {
        console.log(err);
    });

Nolan covers this very well in his post "We have a problem with promises".

Upvotes: 1

Related Questions