title: Using Webworkers in angular app (service worker cache access of data in angular-cli)
body: <p>I wish to run an function (in the background) using a worker. The data comes from a http request. I am using a mock calculation <code>(e.data[0] * e.data[1] * xhrData.arr[3])</code> (replaced by a function returning the actual algo result) as below:</p>
  <pre><code>var ajax =  function() {
      var prom = new Promise(function(resolve, reject){
          if (!!XMLHttpRequest) {
              var xhttp = new XMLHttpRequest();
              xhttp.onload = function () {
                  if (this.readyState == 4 &amp;&amp; this.status == 200) {
                      resolve(JSON.parse(this.responseText));
                  }
              };
         // Cache Logic - Will be adding logic to check cache 
         // if test.json is in cache.
         // If it is then fetch res from cache
         // There will be multiple XHR requests in parallel, not one
              xhttp.open(&quot;GET&quot;, &quot;test.json&quot;, true);
              xhttp.send();
          }
      });
      return prom;
  }
  
  async function test (e) {
      var workerResult, xhrData;
     try {
      xhrData  = await ajax();
      workerResult = (e.data[0] * e.data[1] * xhrData.arr[3]);
      postMessage({res: workerResult});
     } catch(err) {
      postMessage({err: 'Failed'});
     }
  }
  
  onmessage = function (e) {
      test(e);
  };
  </code></pre>
  <p>This works fine. But, this is a pure JS implementation. I was planning to use a service (plus a shared worker) for this so I create only one worker per angular app and dont have memory issues. This is going to be a trigger from a user button action of form submit.</p>
  <p>My question:</p>
  <p>First, I am wondering if this can be done by service workers in Angular itself since it is also a type of background worker thread.</p>
  <p>Second, If not possible then can I access the cache of service workers from web worker? and Is it possible to access this service worker cache. How is this supposed to be done? Any help is welcome.</p>
  <p>Note that I am able to work with service workers and I am able to cache all static assets using angular service workers.</p>
  <h2>Update:</h2>
  <p>I was able to get some basic idea of enabling data cache in the angular app using following config which I am currently working on.</p>
  <pre><code>{
      &quot;name&quot;: &quot;someapi&quot;,
      &quot;urls&quot;: [&quot;/someuri&quot;, &quot;/users&quot;],
      &quot;cacheConfig&quot;: {
        &quot;strategy&quot;: &quot;freshness&quot;,
        &quot;maxSize&quot;: 20,
        &quot;maxAge&quot;: &quot;1h&quot;,
        &quot;timeout&quot;: &quot;5s&quot;
      }
    }
  </code></pre>
  <h2>Update:</h2>
  <p>I was able to get this up and running in a crude but it worked. Added the asset that needed the XHR request into the ngsw-config.json in the assets section. This cached the request into service worker cache. The service workers cache can be opened using <code>caches.open('ngsw:db:${name}')</code> but I did not have to do that.</p>
  <pre><code>I created a web worker file inside the assets folder
  The XHR request was made in it. 
  When a XHR was made the service worker automatically picked up the cache
  So I did not have to use any alternate methods of cache access.
  Sworkers was automatically served the XHR request from the cache.
  </code></pre>
  <p>Here is how I achieved that. I created a service in angular for the service worker:</p>
  <pre><code>@Injectable({
    providedIn: 'root'
  })
  export class WebworkerService {
    myWorker: any;
    constructor() {
        this.myWorker = new Worker('/assets/web-worker.js');
        this.myWorker.onmessage = function(data) {
          console.log(data);
        }
    }
  
  }
  </code></pre>
  <p>Then I created a <code>web-worker.js</code> file in the assets folder:</p>
  <pre><code>var ajax =  function() {
      var prom = new Promise(function(resolve, reject){
          if (!!XMLHttpRequest) {
              var xhttp = new XMLHttpRequest();
              xhttp.onload = function () {
                  if (this.readyState == 4 &amp;&amp; this.status == 200) {
                      resolve(this.responseText);
                  }
              };
              xhttp.open(&quot;GET&quot;, &quot;/assets/test.md&quot;, true);
              xhttp.send();
          }
      });
      return prom;
  }
  
  async function test (e) {
      var workerResult, xhrData;
     try {
      xhrData  = await ajax();
      workerResult = xhrData; // Some calculation or activity here
      postMessage({res: workerResult});
     } catch(err) {
      postMessage({err: 'Failed'});
     }
  }
  
  onmessage = function (e) {
      test(e);
  };
  </code></pre>
  <p>My <code>ngsw-config.json</code> had assets section which cached assets/test.md:</p>
  <pre><code>{
      &quot;name&quot;: &quot;assets&quot;,
      &quot;installMode&quot;: &quot;lazy&quot;,
      &quot;updateMode&quot;: &quot;prefetch&quot;,
      &quot;resources&quot;: {
        &quot;files&quot;: [
          &quot;/assets/**&quot;
        ]
      }
    }
  </code></pre>
  <p>From the component, say for example, app.component.ts I triggered a postMessage()</p>
  <pre><code>@Component({
    selector: 'app-root',
    template:`
   &lt;h1 (click)=&quot;myHttp()&quot;&gt;
      Some Client Event
    &lt;/h1&gt;
  `,
    styleUrls: ['./app.component.css'],
    providers: []
  })
  export class AppComponent {
    constructor(private _ww: WebworkerService) { }
    myHttp() {
      this._ww.myWorker.postMessage('Test');
    }
  
  }
  </code></pre>
  <p>This makes the web-worker.js trigger the XHR request. Though I was expecting I will have to use a cache access api my self, it was not so. The service worker automatically served the file from the cache (Which is fantastic). However if there is a need to access the cache I found this can be done using the cache API here: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache" rel="nofollow noreferrer">https://developer.mozilla.org/en-US/docs/Web/API/Cache</a></p>
  <p>I am sure things can be bettered and file structuring can be made cleaner as per best practices. If you find a better solution please leave an answer so it helps everyone.</p>