I\'m having a hard time integrating angulars service worker into my application. I followed the guide and it works so far. I can create a shortcut on my homescreen and launc
After every other solution on the stack didn't work, I've started debugging angular's ngsw-worker.js script. I've traced the updating logic and ended up in the "PrefetchAssetGroup" method. I've inserted logging every time method got called and then I realized that it is constantly trying to cache my favicon.ico. I've checked the location of the favicon.ico in my ngsw.json and realized that favicon is not located there. Once I've placed the icon on that location everything started working fine.
Making changes to your application you need to this method activateUpdate(
import { SwUpdate } from '@angular/service-worker';
export class AppComponent implements OnInit {
constructor(private swUpdate: SwUpdate) { }
ngOninit() {
this.swUpdate.available.subscribe(event => {
console.log('A newer version is now available. Refresh the page now to update the cache');
});
this.swUpdate.checkForUpdate()
}
}
Check this Link:https://angular.io/guide/service-worker-getting-started
You will probably need to tell the service worker to check the server for updates, I usually use a service for this:
export class UpdateService {
constructor(public updates: SwUpdate) {
if (updates.isEnabled) {
interval(6 * 60 * 60).subscribe(() => updates.checkForUpdate()
.then(() => console.log('checking for updates')));
}
}
public checkForUpdates(): void {
this.updates.available.subscribe(event => this.promptUser());
}
private promptUser(): void {
console.log('updating to new version');
this.updates.activateUpdate().then(() => document.location.reload()));
}
In your app-component.ts
:
constructor(private sw: UpdateService) {
// check the service worker for updates
this.sw.checkForUpdates();
}
main.ts
:
Replace:
platformBrowserDynamic().bootstrapModule(AppModule);
With:
platformBrowserDynamic().bootstrapModule(AppModule).then(() => {
if ('serviceWorker' in navigator && environment.production) {
navigator.serviceWorker.register('ngsw-worker.js');
}
}).catch(err => console.log(err));
I found the following info in the angular docs: https://angular.io/guide/service-worker-devops#debugging-the-angular-service-worker
Summary: There's a useful endpoint on angular sites that shows the service worker state:
http://site-url/ngsw/state
Append /ngsw/state
to your sites address. If there is something wrong with the service it should show there.
To check if newer a version of Angular is available, you can call below method from any component, or just copy the IsNewerVersionAvailable
method in app.component
.
export class DataService {
constructor(private http: HttpClient, private swUpdate: SwUpdate) { }
private available: boolean = false;
IsNewerVersionAvailable() {
if (this.swUpdate.isEnabled) {
this.swUpdate.available.subscribe(() => {
this.available = true;
});
console.log(this.available);
}
return this.available;
}
}
This worked for me on all devices mac/windows/ios/android
export class PwaUpdateService {
updateSubscription;
constructor(public updates: SwUpdate) {
}
public checkForUpdates(): void {
this.updateSubscription = this.updates.available.subscribe(event => this.promptUser());
if (this.updates.isEnabled) {
// Required to enable updates on Windows and ios.
this.updates.activateUpdate();
interval(60 * 60 * 1000).subscribe(() => {
this.updates.checkForUpdate().then(() => {
// console.log('checking for updates');
});
});
}
// Important: on Safari (ios) Heroku doesn't auto redirect links to their https which allows the installation of the pwa like usual
// but it deactivates the swUpdate. So make sure to open your pwa on safari like so: https://example.com then (install/add to home)
}
promptUser(): void {
this.updates.activateUpdate().then(() => {
window.location.reload();
});
}
}