'Angular service worker - new link

Say you have a deployed version of your app v2.0 with these router links:

const routes: Routes = [
  {
    path: "home",
    loadChildren: () =>
      import("src/main/home.module").then((m) => m.HomeModule),
  },
  { path: "**", component: 404Component },
];

Then when you add a new router link and you deploy v2.1:

const routes: Routes = [
  {
    path: "home",
    loadChildren: () =>
      import("src/main/home.module").then((m) => m.HomeModule),
  },
  {
    path: "test",
    loadChildren: () =>
      import("src/main/test.module").then((m) => m.TestModule),
  },
  { path: "**", component: 404Component },
];

The app uses a service worker, so users that have visited previously will have the version 2.0 cached.

Now if I share a link to some old users such as: mywebsite.com/test then the old users will get 404 page and 30 seconds later if the user is still on the page, version v2.1 is downloaded in the background and the app refreshes and shows the correct page (TestModule).

Below is my service worker snippets:

Registration

ServiceWorkerModule.register("ngsw-worker.js", {
  enabled: ENV.production,
  registrationStrategy: "registerImmediately",
}),

ngsw-worker.js

{
      "$schema": "./node_modules/@angular/service-worker/config/schema.json",
      "index": "/index.html",
      "assetGroups": [
        {
          "name": "app",
          "installMode": "prefetch",
          "resources": {
            "files": [
              "/favicon.ico",
              "/index.html",
              "/manifest.webmanifest",
              "/*.css",
              "/*.js"
            ]
          }
        }, {
          "name": "assets",
          "installMode": "lazy",
          "updateMode": "prefetch",
          "resources": {
            "files": [
              "/assets/**",
              "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
            ]
          }
        }
      ]
    }

Check for updates:

export class UpdateService {

  constructor(public updates: SwUpdate) {
    if (updates.isEnabled) {
      interval(6 * 60 * 60).subscribe(() => updates.checkForUpdate())
    }
  }

  public checkForUpdates(): void {
    this.updates.available.subscribe(event => {
      this.promptUser();
    });
  }

  private promptUser(): void {
    this.updates.activateUpdate().then(() => document.location.reload()); 
  }
}

Is there any way to force the new version?



Solution 1:[1]

As far as I know there is unfortunately no way to force the update on application load, but you could improve the 30 seconds wait time. In your constructor instead of interval use timer which will check for update immediately. So your application will update around 5 seconds.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yusuf Ipek