Reputation: 422
I have a function that may either create or update documents in PouchDB, as follows. The function works perfectly when run the first time. However, every subsequent run yields a 409 error, even though the ._rev property appears to be correct.
function saveEventMatchesToDatabase(event, db) {
/* event: An event object from The Blue Alliance API. */
/* db: a reference ot the PouchDB database. */
/* Purpose: Given an event, extract the list of matches and teams, and save them to the database. */
TBA.event.matches(event.key, function(matches_list) {
var i = 0;
for (i = 0; i < matches_list.length; i++) {
var match = new Object();
var docrec = new Object();
match._id = 'matches/' + matches_list[i].key;
match.redTeam = matches_list[i].alliances.red.teams;
match.blueTeam = matches_list[i].alliances.blue.teams;
/* If the doc already exists, we need to add the _rev to update the existing doc. */
db.get(match._id).then(function(doc) {
match._rev = doc._rev;
docrec = doc;
}).catch(function(err) {
if ( err.status != 404 ) {
/* Ignore 404 errors: we expect them, if the doc is new. */
console.log(err);
}
});
db.put(match).then(function() {
// Success!
}).catch(function(err) {
console.log('\ndoc._rev: ' + docrec._rev);
console.log('match._rev: ' + match._rev);
console.log(err);
});
}
});
}
Sample console output from running this function the second time is below. The same error occurs for EVERY item in match_list, not just intermittently.
doc._rev: 1-7cfa2c6245dd939d8489159d8ca674d9
match._rev: 1-7cfa2c6245dd939d8489159d8ca674d9
r {status: 409, name: "conflict", message: "Document update conflict", error: true}
I'm not sure what I'm missing, that's causing this problem. Any suggestions for where to look next would be greatly appreciated.
Upvotes: 6
Views: 9932
Reputation: 11620
The first problem seems to be that you're using a function within a loop, meaning that any variables used inside of the inner functions are randomly changing under your feet depending on when the function gets invoked. Instead of a for loop, you can use forEach()
.
However, the second problems is that you are not using promises correctly; you need to wait for the result of get()
before you do your put()
. So probably forEach()
is not even what you want in the first place; you probably want to use Promise.all()
and then compose your promises.
I wrote a piece on this awhile back; many people have told me that it's worth reading even though it's long: "We have a problem with promises." Read that, and you should hopefully understand promises by the end of it. :)
Upvotes: 13