PouchDB sync not giving a complete event
Asked Answered
N

1

6

My PouchDB sync code is not producing a complete event.

I do get change and active and paused events (in that order), and the databases do eventually sync (after a very long wait even though there is not much data).

I need the complete event so I know when the remote CouchDB data is available locally to be used.

My code looks like this:

  init(localDBName, remoteDBName)
  // Initialises the database - Called every time the App starts or the user logs in or registers
  // If remoteDBName is false we don't want to sync data to the server
  {

    // Create a new database or open it if it already exists
    this._DB = new PouchDB(localDBName);
    this.remote = remoteDBName;          // If remoteDBName is false we don't sync data to the server

    console.log('Data: init(): PouchDB database opened for localDBName = ' + localDBName + ' : ' + this._DB + ', remoteDBName = ' + this.remote);

    // Sync to remote DB if we have been asked to
    if (this.remote)
    {
      // Insert the url for the CouchDB server into the remoteDBName returned by PouchDB
      var realRemoteDB = this.remote.replace("localhost:5984", COUCHDB_SERVER_URL);

      console.log('Data: init: remoteDB path being used is: ' + realRemoteDB);

      let options = {
        live: true,
        retry: true,
        continuous: true
      };

      return this._syncHandler = this._DB.sync(realRemoteDB, options)
        .on('complete', (info) => {
          console.log('***** DATA: init() Complete: Handling syncing complete');
          console.dir(info);
        })
        .on('change', (info) => {
          console.log('***** DATA: init() Change: Handling syncing change');
          console.dir(info);
        })
        .on('paused', (info) => {
          console.log('***** DATA: init() Paused: Handling syncing pause');
          console.dir(info);
        })
        .on('active', (info) => {
          console.log('***** DATA: init() Active: Handling syncing resumption');
          console.dir(info);
        })
        .on('error', (err) => {
          console.log('***** DATA: init() Error: Handling syncing error');
          console.dir(err);
        })
        .on('denied', (err) => {
          console.log('***** DATA: init() Denied: Handling syncing denied');
          console.dir(err);
        });
    }
    else {
      this.syncHandler = null;
    }
  }

The last event I get is the paused event which fires just after change event shows the data has been pulled from the server.

Nightgown answered 31/3, 2017 at 10:25 Comment(0)
G
15

This is actually the way it should work ;)

The sync method behaves differently depending on the options you specify:

  • Without live option: In a normal syncronisation (without the live option) the complete event will work just as you thought it would: It will trigger once the syncronisation completes.

  • With live option: In a live replication/synchronisation the syncronisation will never complete as it is continuous. The complete event will only be triggered if the replication is cancelled. See the docs here (I highlighted the important part):

    complete (info) - This event fires when replication is completed or cancelled. In a live replication, only cancelling the replication should trigger this event.


To solve your problem you could initially do a synchronisation without the live option. If this synchronisation completes your remote data should be available locally.

Now in the complete event handler, you can start a live replication to start your continuous synchronisation.

The code might look like this:

this._DB.sync(realRemoteDB) //No options here -> One time sync
        .on('complete', (info) => {              
          this._DB.sync(realRemoteDB, options); //Continous sync with options
        });
Gewgaw answered 31/3, 2017 at 11:34 Comment(4)
Thanks @phonolog. I had taken "when replication is completed or cancelled" to mean the even should fire when the replication is completed OR cancelled. I have tried syncing without live but it still takes a very long time to complete and I need to know when it has so I am not sure how your code will give me that.Nightgown
I feel like I didn't make my point right... See my edited answer: The sync method behaves differently if you use the live option.Gewgaw
Thanks for the extra explanation @phonolog makes sense now.Nightgown
How about the change event.const remoteDatabase = new PouchDB(remote); this.localdb.sync(remoteDatabase, { since: 'now', live: true, retry: true, // include_docs: true, }).on('change', (change: any) => { console.log('changed item' + change); this.listener.emit(change); console.log(change); }). The change never triggersCoinage

© 2022 - 2024 — McMap. All rights reserved.