If you've setup a service worker for your app using the @angular/service-worker package, you may be wondering about how to deal with stale versions of your app for end users. This can easily become a problem because new versions of a service worker will only be activated on page reload.

Thankfully, @angular/service-worker has a <^>SwUpdate<^> class that makes it easy to check for available updates.

Subscribing to Available Updates

service worker illustration for: Subscribing to Available Updates

Let's go over SwUpdate's basic usage by creating an <^>Update<^> service that subscribes to the <^>available<^> observable, which emits when there's a service worker update available:

				
					
[label update.service.ts]

import { Injectable } from '@angular/core';



&lt;^&gt;import { SwUpdate } from '@angular/service-worker';&lt;^&gt;



				
			

A simple page reload will do the trick to activate the new service worker, so the update logic could use something like a snackbar component to prompt the user to reload the page. Angular Material has a great snackbar component that could be used like the following:

				
					
[label update.service.ts]

import { Injectable } from '@angular/core';



import { MatSnackBar } from '@angular/material';

import { SwUpdate } from '@angular/service-worker';

@Injectable()

export class UpdateService {

  constructor(private swUpdate: SwUpdate, private snackbar: MatSnackBar) {

    this.swUpdate.available.subscribe(evt =&gt; {

      const snack = this.snackbar.open('Update Available', 'Reload');

  snack

    .onAction()

    .subscribe(() =&gt; {

      window.location.reload();

    });



  snack.setTimeout(() =&gt; {

    snack.dismiss();

  }, 6000);

});

				
			

Then we'd just have to make sure that our <^>Update<^> service is provided in the app module and that it's injected in the app component:

				
					
[label app.component.ts]

import { Component } from '@angular/core';



&lt;^&gt;import { UpdateService } from './update.service';&lt;^&gt;



				
			

And that's it for a basic update mechanism. Let's now have a look at a few more properties and methods available as part of the SwUpdate class.

activated & isEnabled

SwUpdate has an <^>activated<^> observable that's similar to the <^>available<^> observable and that can be subscribed to in order to hook onto successful service worker activations.

Additionally, there's an <^>isEnabled<^> property that returns true if the service worker is currently enabled:

				
					
import { Injectable } from '@angular/core';

import { SwUpdate } from '@angular/service-worker';



@Injectable()

export class UpdateService {

  constructor(private swUpdate: SwUpdate) {

    if (!this.swUpdate.isEnabled) {

      console.log('Nope 🙁');

    }

  }

}

				
			

checkForUpdate() & activateUpdate()

The SwUpdate class also has two methods that allow us more control over service worker updates:

  • <^>checkForUpdate()<^>: Allows to check for updates periodically.
  • <^>activateUpdate()<^>: Allows us to force a service worker update.