1

On button click I successfully register for sync and it fires the functionality I've described in the service-worker. If I'm offline - it waits for the browser to get connection and then it fires.

BUT - when I click the button the first time and all is fine - from then on clicking the button again successfully registers for sync, but the sync event in the service-worker never triggers:

self.addEventListener('sync', function(event) {
    console.log('EVENT in SYNC', event);
}

I see the console logging only the first time I click the button. Am I missing something?

pesho hristov
  • 1,946
  • 1
  • 25
  • 43
  • 2
    Have you checked out https://jakearchibald.github.io/isserviceworkerready/demos/sync/ and confirmed that your code is doing the same thing? If that doesn't help, can you please post both the relevant portions of both your client page and your service worker code? – Jeff Posnick Jan 26 '17 at 16:08
  • Oh ... I fixed that ... and forgot to write down the solution ... sorry. Please, take a look at the answer :) – pesho hristov Jan 26 '17 at 18:36

2 Answers2

2

I figured it out :) ... and the problem was pretty lame: the sync handler in the service worker was returning a promise, but this promise never got resolved. Once I added the resolve() part in the handler returned promise - it all worked fine.

PS: In the Jake Archibald's demo the sync handler was doing self.registration.showNotification, which returns a promise, and this promise resolves once the notification is shown. On other examples they make simple fetch, which also returns promise, and that promise resolves on success. But on my example - I was pulling data from indexedDB and then making fetch. So - just wrapped everything in

var p = new Promise(function(resolve, reject) {
    // get data from indexedDB .. 
    fetch(...).then(function(response) {
        return response;
    })
    .then(function() {
        // fetch was successful .. 
        resolve();
    });
};
return p;

This way it worked correctly.

pesho hristov
  • 1,946
  • 1
  • 25
  • 43
  • You should mark your answer as correct if this is your fitting solution.. It gave me the right hint ;) – goemic Feb 03 '18 at 23:51
0

These API's are very experimental and they are most likely to change, so don't take my word for it. I don't have any piece of documentation to support my experience.

In my case, 'sync' event is triggered only once, by design. So I made it work as I wanted by registering to the SyncManager after enqueuing every must-send request:

self.addEventListener('fetch', evt=> {
  if(isSuperImportant(evt.request)) {
    evt.respondWith(Promise.resolve(new Response({status: 201})));
    evt.waitUntil(
      myEnqueue(evt.request).then(()=> {
        return self.registration.sync.register('sync-tag'); 
      })
    );
  }
  else {
    // process the non-important requests
  }
});


self.addEventListener('sync', evt=> {
  evt.waitUntil(tryToFlushMyQueue());
});
rodix
  • 425
  • 4
  • 13