Reputation: 1375
I have a gulp setup that puts all my html in template cache for faster access in angular. I'm trying to add a service worker to my project, using sw-precache, so that it can be used offline. If I'm connected to the network, everything works fine. When I go offline, the requests for html resources (that are in the template cache) fail because it seems it is requesting the path from the network.
Is there something I need to add to my sw-precache config in order to have it defer to angular to handle retrieval of html files?
Upvotes: 0
Views: 885
Reputation: 46
my original solution was not 100%
To solve this, use sw-precache and sw-toolbox
Using a gulp configuration you can setup sw-precache to cache you content and extend this with sw-toolbox to use cached responses based upon routing configuration
see: https://developers.google.com/web/ilt/pwa/using-sw-precache-and-sw-toolbox
Upvotes: 1
Reputation: 46
ok, so this is how I solved this. I am using Angular JS 1.6.4 with sw-precache.
I have CacheStorage via service workers, so using service workers I know I am expecting devices to support certain functionality, in my case we know our users will have Android Tablets with Chrome and support is valid.
I am developing a progressive web app with offline functionality.
So, the theory...I have directives which have templateUrls.
Using this post: https://thinkster.io/templatecache-tutorial
I basically have my directive code:
angular.module('app').directive('location',
['$timeout', 'notify.service', 'user.settings.service', 'log.service',
function ($timeout, notify, userSettings, log) {
return {
restrict: 'EA',
... controller etc..,
templateUrl: '/App/core/directives/location.html'
}
}
]);
Now, when this app goes offline, the cached instances of the content was not kicking it - annoying.
So, after much procrastinating I got down and dirty.
My solutio is, keep the templateUrl as it is, but overwrite the content via the $templateCache service.
To do this, you append a RUN function with your directive (for clarity). We know the service worker cache representation of our Url files contains the common path, in my case: '/App/core/directives/location.html'.
So, using new technology in the browser, window.caches gives me access to the CacheStorage that the service workers uses, I can then use the API available: https://developer.mozilla.org/en-US/docs/Web/API/Cache
I can then use the match method to find the matching service worker cache content, read that stream of binary and convert to HTML and then tell $templateCache to replace it with the service worker cached value.
So, for completeness (and you can create a common service which replaces the cached values based on templateUrl - which I will be doing for each directive)
(function () {
'use strict';
var templateUrl = '/App/core/directives/location.html';
// <location on-location='someFunc'></location>
// provides a form/control to find a location either by GEO location or manual city search
angular.module('app')
.run(['$templateCache', function ($templateCache) {
var cache = window.caches;
cache.match(templateUrl, { ignoreSearch: true }).then(function (response) {
if (response) {
response.body.getReader().read().then(function (cachedResponse) {
// convert the Uint8Array value to HTML string
var content = new TextDecoder('utf-8').decode(cachedResponse.value);
$templateCache.put(templateUrl, content);
//console.log($templateCache.get(templateUrl)); // debug
});
}
});
}])
.directive('location',
['$timeout', 'notify.service', 'user.settings.service', 'log.service',
function ($timeout, notify, userSettings, log) {
return {
restrict: 'EA',
... controller, scope etc...
templateUrl: templateUrl
}
}
]);
})();
Draw backs...the RUN process is synchronous, so initially they have to hit the site online first...but thats how service worker needs to work anyway, so thats handled in training :)
I expect there to be a better option, but for the time being thats the solution I have, I will be creating a template service for replacing $templateCache values based on the var templateUrl each directive will have, so the code becomes cleaner in each directtive....i considered having a global arr of templates and files, but, just a bit obscure, think its cleaner for each directive
Upvotes: 2