How to update a single field in a pouchDB document
Asked Answered
B

1

6

I create a pouchDB document with "_id", "name", and "status" fields. However, I find that if I want to update the "status" field of the document then I need to also specify all the other fields I am NOT changing as well otherwise they get erased. That is, if I do not specify the "name" field on update, there will no longer be a "name" field on the document.

function createFriendSchedule(friend){

  pouchDB.put({

    _id : friend['id'],
    name : friend['name'],
    status: "new"

  }, function(err, response){

    createAndDispatchEvent("friend Schedule created");

  });


}

This is the code for updating the document

function changeFriendStatus(friend){

  pouchDB.get(friend['id'], function(err, retrieved){

    pouchDB.put({

      _id : friend['id'],
      _rev : retrieved._rev, //need to specify _rev otherwise conflict will occur
      name : retrieved.name, //if you don't specify name should remain the samme as before, then it will be left off the record!
      status : friend['status']

    }, function(err, response){

      if(err){  

    console.log("COULDN'T CHANGE FRIEND STATUS");

      } else {  createAndDispatchEvent("friend status changed") }

    });


  });

}

And here is the code used to pull the record out

  window.pouchDB.query(
    {map : map}, 
    {reduce : false}, 
    function(err, response){

      var responseRows = response['rows'];
      var cleanedList = [];
      _.each(responseRows, function(friend){    

    cleanedList.push({'_id' : friend['key'][0], 'name' : friend['key'][1], 'status' : friend['key'][2] });

      });
      window.reminderList = cleanedList;
      console.log(window.reminderList);
      createAndDispatchEvent("Returned reminder list");

    });

If I don't specify the "name" field on update, the array returned by the emit() call in pouchDB.query contains a null value where I expect the "name" value to be.

Ballarat answered 12/5, 2014 at 9:59 Comment(0)
Y
12

CouchDB and PouchDB are designed in such a way that documents are atomic. So indeed, if you want to update a single field, you have to put() the entire document.

One way to make this easier in your example is to use the retreived value directly, instead of creating a new object and manually copying the fields over. You could also split your documents up into many small documents with multiple types, rather than one single big document that has to be constantly read and re-written.

You may also want to consider using allDocs instead of query, since if you just need to fetch documents by ID, it will typically be faster. The PouchDB blog has a few articles on pagination and indexing that could be helpful here.

Edit: There is now a pouchdb-upsert plugin that makes it easier to update a single field. Under the hood, it just does a put().

Youngstown answered 12/5, 2014 at 18:44 Comment(1)
Thanks for creating such an awesome library :) I really take it for granted all the things that can be done in browser now! I have posted a possible workaround below for anyone that wants to be able to update a single (or multiple) fields without having to explicitly update all others.Ballarat

© 2022 - 2024 — McMap. All rights reserved.