1

I have a question about caching in PWA.
I would like to let user choose a list to cache. For example: User creating few lists, and then he choose one, to save for offline. When he is offline he can only open 2 views:

  1. smth like "u are offline, do you want to open saved list?" (if it exist)
  2. View with saved list.

At this moment, I am caching all views that user visited, but can't cache views with dynamic data.
I'm using PWA.essentials to do PWA.

     services.AddProgressiveWebApp(new PwaOptions
            {
                RegisterServiceWorker = true,
                RegisterWebmanifest = false,
                Strategy = ServiceWorkerStrategy.NetworkFirst,
                RoutesToPreCache = "/, /Home/Offline, /Home/Saved_list",
                OfflineRoute="Offline.html"
            }); 

I have created manifest.json. When im using dev mode in chrome, I can see that at this moment, I'm caching all views execpt views with more complicated path (like /Controller/View/something).


I'm saving list, that user choose in a "Offline.json" file, that is cached too,but when user changes list to save, file "offline.json" is still no updated. I mean my PWA doesn't replace it with new one.

So I have a question about how can I save dynamic list to browser cache, and then set offline route to it.

Service Worker Created by pwa.essentials:

(function () {
    'use strict';

    // Update 'version' if you need to refresh the cache
    var version = 'v1.0::NetworkFirst';
    var offlineUrl = "Offline.html";

    // Store core files in a cache (including a page to display when offline)
    function updateStaticCache() {
        return caches.open(version)
            .then(function (cache) {
                return cache.addAll([
                    offlineUrl,
                    '/','/Home','/Generate/Select_mode'
                ]);
            });
    }

    function addToCache(request, response) {
        if (!response.ok)
            return;

        var copy = response.clone();
        caches.open(version)
            .then(function (cache) {
                cache.put(request, copy);
            });
    }

    self.addEventListener('install', function (event) {
        event.waitUntil(updateStaticCache());
    });

    self.addEventListener('activate', function (event) {
        event.waitUntil(
            caches.keys()
                .then(function (keys) {
                    // Remove caches whose name is no longer valid
                    return Promise.all(keys
                        .filter(function (key) {
                            return key.indexOf(version) !== 0;
                        })
                        .map(function (key) {
                            return caches.delete(key);
                        })
                    );
                })
        );
    });

    self.addEventListener('fetch', function (event) {
        var request = event.request;

        // Always fetch non-GET requests from the network
        if (request.method !== 'GET') {
            event.respondWith(
                fetch(request)
                    .catch(function () {
                        return caches.match(offlineUrl);
                    })
            );
            return;
        }

        event.respondWith(
            fetch(request)
                .then(function (response) {
                    // Stash a copy of this page in the cache
                    addToCache(request, response);
                    return response;
                })
                .catch(function () {
                    return caches.match(request)
                        .then(function (response) {
                            return response || caches.match(offlineUrl);
                        })
                        .catch(function () {
                            if (request.headers.get('Accept').indexOf('image') !== -1) {
                                return new Response('<svg role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' } });
                            }
                        });
                })
        );

    });

})();
jps
  • 20,041
  • 15
  • 75
  • 79
Caran
  • 15
  • 7

1 Answers1

0

You are saving the user selected pages’ list at server side in offline.json and you are caching that file too. As per working of PWA cached resources are served from cache and not from server until cache is removed/cleared.

You can take 2 approach.

  1. Whenever user adds to the offline.json you need enforce service worker to update the offline file.

  2. You can simply store the user selecting in local storage and from there you add pages to cache list.

Rajesh G
  • 639
  • 4
  • 13
  • are you modifying json file based on user selection or not? – Rajesh G Dec 29 '19 at 11:19
  • At this moment I am creating json like ```c# JsonSerializer serializer = new JsonSerializer(); string json = JsonConvert.SerializeObject(currentList); string path = "./wwwroot/OfflineList.json"; System.IO.File.WriteAllText(path, json); ``` and using automatically created Service Workder by PWA essentials. It doesn't cache it again, it just cache it at app lauch. – Caran Dec 29 '19 at 11:21
  • yes, when user select list, I am deleting all data from offline.json and write there new list. – Caran Dec 29 '19 at 11:57
  • as you are caching offline file, you need to updated cache whenever the file gets update. see if this helps https://stackoverflow.com/questions/33262385/service-worker-force-update-of-new-assets – Rajesh G Dec 29 '19 at 15:11
  • But how can I cache data from views with more complicated path or views which takes parameters as input. At this moment when for example I'm caching list with ID X, when im offline I can't open it, even it's in my cache. So I would like to create new with with dynamic data, where I will send for example "last visited list" or as I mentioned before selected list by user. – Caran Dec 29 '19 at 17:18
  • In PWA essential, I can't edit Service Worker, I mean i can only change it's Strategy or smth. But there is no option to edit serviceworker.js at all. – Caran Dec 29 '19 at 17:19
  • I can add the file with list, I mean offlineList.json for precache and then recache it, if its possible whenever User set new list or something – Caran Dec 29 '19 at 17:24