angular / angular/angular

SwUpdate Inconsistent (checkForUpdate does nothing)

Open
#55,975 3 comments 8 reactions 0 assignees View on GitHub
area: service-worker
Dominant language
TypeScript
Stars
101k
Forks
27.5k
Avg merge
1d 19h
Merged PRs (30d)
288

Description

### Which @angular/* package(s) are the source of the bug?

service-worker

### Is this a regression?

No

### Description

I was trying to use a service worker to deliver prompt updates to users actively using the site. Followed the simple steps laid out in: https://angular.io/guide/service-worker-getting-started but I'm having issues with the initial load of the site.

My app.config looks like:
```
export const appConfig: ApplicationConfig = {
providers: [
...
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000',
}),
NewAppVersionTrackerService,
],
};
```

The service watching for updates:
```
@Injectable({ providedIn: 'root' })
export class NewAppVersionTrackerService {
private versionCheckIntervalSeconds = 60;

constructor(
private dialogService: DialogService,
private swUpdate: SwUpdate,
private zone: NgZone,
) {}

public init() {
this.watchForUpdates();
}

private watchForUpdates(): void {
if (!this.swUpdate.isEnabled) return;

console.info(`Version Tracker Initializing`);

this.zone.runOutsideAngular(() => {
interval(this.versionCheckIntervalSeconds * 1000).subscribe(() => {
console.log('Checking for SW Update');
this.swUpdate
.checkForUpdate()
.then((versionFound) => {
console.log('CHECK RESULT:', versionFound);
})
.catch(() => console.log('SW Update check failed?'));
});
});

this.swUpdate.versionUpdates.subscribe((versionEvent) => {
switch (versionEvent.type) {
case 'VERSION_DETECTED':
console.info(`New application version found, beginning download: ${versionEvent.version.hash}`);
break;
case 'VERSION_READY':
console.info(`New app version ready: ${versionEvent.latestVersion.hash}`);
this.dialogService.open(DynamicNewApplicationVersionReadyDialogComponent);
break;
}
});
}
}
```

And my app.component is:
```
export class AppComponent {
constructor(
appRef: ApplicationRef,
private newAppVersionTrackerService: NewAppVersionTrackerService,
) {
this.newAppVersionTrackerService.init();
appRef.isStable.pipe(filter((stable) => stable)).subscribe(() => console.log('App is stable now'));
}
}
```

Those are the only changes I made to the application. But it seems a total crapshoot if the service worked is actually linked to the SwUpdate service the first time you navigate to the page.

Sometimes it looks like:
![image](https://github.com/angular/angular/assets/11820009/e68f72f2-a0f5-4fb1-8638-9b1c0658992e)
Which is great, the `checkForUpdate` is returning a value and when I deploy a new version I see the dialog and can refresh.

**But** sometimes on initial load instead I get this:
![image](https://github.com/angular/angular/assets/11820009/8f5c8ade-9a33-4803-8a76-50270c3002fc)

The app is apparently still stable, and I can see the SW is registered in the Application tab of the chrome dev tools. But the `checkForUpdate` promise doesn't actually do anything, it doesn't resolve _or_ reject. And new deployments are never detected.

All of the first load testing is done through new instances of the chrome incognito windows.

Refreshing the page does return this to working correctly, but it would be great if the `checkForUpdate()` promise would work consistently for first time users as well.

### Please provide a link to a minimal reproduction of the bug

_No response_

### Please provide the exception or error you saw

_No response_

### Please provide the environment you discovered this bug in (run `ng version`)

```true
Angular CLI: 17.3.7
Node: 18.18.0
Package Manager: pnpm 9.0.6
OS: win32 x64

Angular: 17.3.8
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker

Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1703.7 (cli-only)
@angular-devkit/build-angular 17.3.7
@angular-devkit/core 17.3.7
@angular-devkit/schematics 17.3.7
@angular/cli 17.3.7
@angular/pwa 17.3.7
@schematics/angular 17.3.7
rxjs 7.8.1
typescript 5.4.5
zone.js 0.14.5
```

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the initial-load path through provideServiceWorker, SwUpdate.checkForUpdate(), and the AppComponent initialization shown in the report. Reproduce the first visit in a new incognito window and inspect when service-worker registration becomes available. Done means checkForUpdate() consistently resolves or rejects and newly deployed versions are detected without requiring a refresh.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.