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.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Bill Noble
  • 6,466
  • 19
  • 74
  • 133

1 Answers1

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
        });
Community
  • 1
  • 1
Phonolog
  • 6,321
  • 3
  • 36
  • 64
  • 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. – Bill Noble Mar 31 '17 at 12:16
  • 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. – Phonolog Mar 31 '17 at 16:40
  • 1
    Thanks for the extra explanation @phonolog makes sense now. – Bill Noble Mar 31 '17 at 17:30
  • 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 triggers – Eldho Oct 21 '19 at 11:51