Table of Contents
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
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';
<^>import { SwUpdate } from '@angular/service-worker';<^>
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 => {
const snack = this.snackbar.open('Update Available', 'Reload');
snack
.onAction()
.subscribe(() => {
window.location.reload();
});
snack.setTimeout(() => {
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';
<^>import { UpdateService } from './update.service';<^>
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.