Progressive Angular apps

Ac4189b770a4dbc0078935a68fff6f5c?s=47 Ciro Nunes
November 22, 2016

Progressive Angular apps

20 minutes talk about Progressive Web Apps with Angular 2

Ac4189b770a4dbc0078935a68fff6f5c?s=128

Ciro Nunes

November 22, 2016
Tweet

Transcript

  1. 3.
  2. 4.
  3. 5.
  4. 11.
  5. 17.

    { "name": "Ali Express", "short_name": "AliExpress", "icons": [{ "src": "images/icons/icon-128x128.png",

    "sizes": "128x128", "type": "image/png" }], "start_url": "/index.html", "display": "standalone", "background_color": "#3E4EB8", "theme_color": "#2F3BA2" } manifest.webapp
  6. 20.
  7. 21.
  8. 22.
  9. 27.

    var cacheName = 'myApp'; var filesToCache = [...]; self.addEventListener('install', function(e)

    { e.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }) ); }); service-worker.js ADD TO CACHE
  10. 28.

    self.addEventListener('activate', (e) => { e.waitUntil(self.clients.claim()); e.waitUntil( caches.keys().then((keyList) => { return

    Promise.all(keyList.map((key) => { if (key !== cacheName) { return caches.delete(key); } })); }) ); }); service-worker.js CLEAR CACHE
  11. 31.

    self.addEventListener('fetch', function(e) { var dataUrl = 'https://sample-api.com'; if (e.request.url.indexOf(dataUrl) >

    -1) { e.respondWith( caches.open(dataCacheName).then(function(cache) { return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; }); }) ); } else { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); } }); service-worker.js
  12. 32.

    self.addEventListener('fetch', function(e) { var dataUrl = 'https://sample-api.com'; if (e.request.url.indexOf(dataUrl) >

    -1) { e.respondWith( caches.open(dataCacheName).then(function(cache) { return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; }); }) ); } else { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); } }); service-worker.js
  13. 33.

    self.addEventListener('fetch', function(e) { var dataUrl = 'https://sample-api.com'; if (e.request.url.indexOf(dataUrl) >

    -1) { e.respondWith( caches.open(dataCacheName).then(function(cache) { return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; }); }) ); } else { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); } }); service-worker.js
  14. 34.

    self.addEventListener('fetch', function(e) { var dataUrl = 'https://sample-api.com'; if (e.request.url.indexOf(dataUrl) >

    -1) { e.respondWith( caches.open(dataCacheName).then(function(cache) { return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; }); }) ); } else { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); } }); service-worker.js
  15. 35.
  16. 36.

    caches.match(e.request.clone()).then((response) => { return response || fetch(e.request.clone()).then((theResponse) => { return

    caches.open(dataCacheName).then((cache) => { cache.put(e.request.url, theResponse.clone()); return theResponse.clone(); }); }); }); service-worker.js
  17. 37.
  18. 40.
  19. 41.
  20. 42.
  21. 44.
  22. 45.
  23. 47.
  24. 49.

    ~ $ npm i --save @angular/app-shell // App code import

    { AppShellModule } from '@angular/app-shell'; @NgModule({ bootstrap: [AppComponent], imports: [ BrowserModule, AppShellModule.runtime(), AppModule })
  25. 50.

    @Component({ selector: 'app-root-component', template: ` <!-- Only show loading indicator

    in the shell --> <loading-indicator *shellRender> </loading-indicator> <!-- Hide a dynamic view until runtime --> <dynamic-view *shellNoRender> </dynamic-view> ` }) export class AppRootComponent {}
  26. 52.
  27. 56.

    ~ $ npm i --save @angular/service-worker // worker-basic.min.js is copied

    from // node_modules/@angular/service-worker/bundles if (navigator.serviceWorker) { navigator.serviceWorker.register('/worker-basic.min.js'); }
  28. 57.

    { "routing": { "routes": { "/": { "prefix": false }

    }, "index": "/index.html" } } ngsw-manifest.json
  29. 59.

    self.addEventListener('push', function(e) { e.waitUntil( fetch('http://localhost:8090/pushdata').then(function(response) { return response.json(); }).then(function(data) {

    return self.registration.showNotification(title, { body: body, icon: icon, tag: tag }); }, function(err) { err(err); }) ); }); worker-push.js
  30. 60.

    self.addEventListener('push', function(e) { e.waitUntil( fetch('http://localhost:8090/pushdata').then(function(response) { return response.json(); }).then(function(data) {

    return self.registration.showNotification(title, { body: body, icon: icon, tag: tag }); }, function(err) { err(err); }) ); }); worker-push.js
  31. 61.