Where should an EventListener be added in an Angular Service Worker?

I am currently in the process of developing an Angular Progressive Web Application (PWA) with offline capabilities. While I have made significant progress, I am facing challenges regarding events for the service worker. Specifically, I am unsure about where to correctly implement the addEventListener(..). Most tutorials suggest using a separate service-worker.js file, but that approach feels awkward to me within a TypeScript environment. Moreover, I would like to leverage my Angular Services to interact with the backend, which seems unattainable from a standalone .js file.

In an attempt to address this issue, I created a Service to register a periodicSync and tried to listen to the event. Although the periodic sync is successfully registered in Chrome, the event is not being captured by the listener.

export class SyncService{

constructor(indexedDbService: IndexedDbService, apiService: ApiService)
{}

   public RegisterSyncStuff(){
    //Works fine
    const registration : any = await navigator.serviceWorker.ready;
    try {
        await registration.periodicSync.register('download-stammdaten',{
           minInterval:  30 * 1000,
         });
     } catch {
        Console.log('no periodicSync possible')
     }
     //Does not work at all. 
     addEventListener('periodicSync', () => {
         let stuffToStore = this.apiService.getStuff();
         indexDbSerivce.StoreStuff(stuffToStore);
     })
  }

}

Answer №1

In a TypeScript environment, you can develop the worker, but in the browser it runs as a *.js file.

To establish communication between the service-worker.js file and another part of your code, utilize event listeners and posting messages as shown below:

service-worker.js

addEventListener('message', ({data}) => {
  if (data) {
    console.log('Hello from worker!')
    let newDataInArray = [data]
    postMessage(newDataInArray);
  }
});

Consider a DataService module like data-service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  someDataInService: Data = {data};

  constructor() {}

  sendDataToWorker() {
    runWorker(this.someDataInService);
  }

  async runWorker(data: Data) {
    if (typeof Worker !== 'undefined') {

      // Spawn a worker
      const worker = new Worker(new URL('./app.worker', import.meta.url)); 

      // Send data to the worker
      worker.postMessage(data); 

      // On message return from worker
      worker.onmessage = (dataInArray) => { 
        // manipulate dataInArray here
      };
    } else {
      // Handle fallback scenario
    }
  }
}

If a worker is already spawned, there is no need to create a new one unless multiple instances are preferred. Reuse the existing worker by simply posting a message to the instance using worker.postMessage().

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the benefits and drawbacks of utilizing two distinct methods to regulate a component in Vue?

I've developed two components that display "on" or "off" text, along with a button that toggles the state of both components. Here is the link to the codesandbox for reference: https://codesandbox.io/s/serene-mclean-1hychc?file=/src/views/Home.vue A ...

Is there a way to ensure that an Observable is only returned from this method after a file has been fully uploaded to Firebase Storage?

Struggling with uploading a file to Firebase Storage from my Angular app. The current situation is as follows: within a service class, the code snippet looks like this: if(file != null) { this.uploadFileIntoFirebaseStorage(file) .subscribe(url ...

The method _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵvid"] cannot be executed as a function

While conducting E2E tests for my Angular 6 application using Cypress, I encounter an intermittent error: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵvid"] Strangely, making a minor code change sometimes resolves the issue. I am puzzled as to why this ...

The styles and scripts in Angular.json are not functioning properly

Attempting to integrate Bootstrap into my Angular project, but encountering issues with Scripts and Styles in angular.json After trying to copy the path from the folder, I keep getting errors! "styles": [ "C:\AngularProjects\project1\no ...

Set Ngx admin background image as your design foundation

Looking to add a background image to ngx-admin Check out this link for more information My goal is to achieve a similar look to this example. Sincerely, Gopi ...

Utilizing the ABP framework for implementing pagination in ngx datatable

Is there a way to display pagination footer in ngx datatable within the abp framework for Angular? I am currently using ListService with PagedResultDto. Do I need to implement pagination externally? <ngx-datatable [scrollbarH]="false&quo ...

Are you on the lookout for an Angular2 visual form editor or a robust form engine that allows you to effortlessly create forms using a GUI, generator, or centralized configuration

In our development team, we are currently diving into several Angular2< projects. While my colleagues are comfortable coding large forms directly with Typescript and HTML in our Angular 2< projects, I am not completely satisfied with this method. We ...

Typescript causing issues with Material-UI theme.mixins.toolbar functionality

Currently, I am utilizing Material-UI to develop a React and Typescript website. The experience has been positive overall, but I am facing a specific issue. I have been trying to implement one of the code examples from their documentation, but unfortunatel ...

What is the process for creating a map in which the value type is determined by the key type?

Is it feasible to formulate a Map<K, V> in a manner where the type of the value relies on the type of the key, without explicitly specifying the key's type upon initializing the map? For instance: abstract class BaseA { a() {} } class ConcreteA1 ...

Wrapping components in Angular 4 with _ngcontent-cx divs

Currently, I am facing a situation in one of my Angular templates where I have an ngFor loop that involves another component. Here is a snippet of the code: <div *ngFor="let thing of things" (click)="onClick($event, thing)"> <app-thing [data] ...

Utilize JQuery to choose the angular element

Can Angular tags be selected using JQuery? I am currently utilizing the ui-select Angular component, which is integrated into the HTML page as shown below: <ui-select ng-model="rec.currencyCode" on-select="ctrl.selectCurrencyCode(rec, $item)"> & ...

Is Webpack capable of adjusting public paths dynamically?

Currently, I have an application running on express js and angular 2. To bundle my modules, I am using webpack and utilizing webpack dev middleware to run webpack with express. In order to serve the index.html file for all routes, I have configured a wild ...

Utilizing a Storybook default export (without a specific name) along with a template rather than a component

Utilizing storybook, you have the ability to create a named story template by: export default { title: 'My Component', } as Meta; export const Default: Story<any> = () => ({ template: ` <p>My story</p> ` }); Displa ...

Generate random entries from an object based on specific criteria and append them to a fresh object using Typescript

Experimenting with Ionic2 and Typescript has been my recent focus. I have an object that contains various meals, calorie counts, and meal types (such as vegan). This is how the object looks: [ { "id":14093, "name":"Proteinshake mit Wasser ...

How to efficiently pass props through interfaces in a TypeScript functional component

Error: https://i.sstatic.net/SDwHN.png I encountered an error and found a solution by adding a question mark on my interface. However, I was under the impression that it should work without the need for a question mark. Do you think adding a question mar ...

Reactive sidenav in action with Angular

Exploring the creation of a reactive component for educational purposes, disregarding project structure =). My directory layout: app.component.html <app-header></app-header> <app-sidenav></app-sidenav> <app-footer></app ...

Is it possible to implement the bootstrap grid system within my Angular components using grid classes?

Looking for something along the lines of <my-row> <my-col>Content</my-col> <my-col>Content</my-col> </my-row> Having the bootstrap classes within my components. This method was effective with Bootstrap 3, however th ...

Is it feasible to trigger a selector element in Angular 2 upon clicking another element?

I want to trigger the Angular2 Material Datepicker's calendar popup by clicking on another element on the page. More specifically: <material-datepicker> </material-datepicker> should be triggered when a specific text is clicked: <p&g ...

Encountering difficulties with installing bootstrap-vue

While attempting to integrate Bootstrap-Vue into my project that includes Vuex, Vue-Router, TypeScript, and Babel, I encounter an error in the browser. To replicate docker run -it --rm -p 8080:8080 node:17.7.2-alpine yarn global add @vue/cli vue create ...

Error in TypeScript: The type of JSX element does not provide any construct or call signatures

I am currently working with React version 16.2.0 and TypeScript version 2.7.1, where the use of any as a type is not permitted. The primary component: // index.js import * as React from 'react' import Page from './page' import i18n f ...