Is ngOnDestroy executed within Angular services?

Is there a way to confirm if the ngOnDestroy method in my UserServiceService class is functioning properly? I want this service to continue running until the project starts and ends, with ngondestroy method executing once the application (website) is closed.

export class UserServiceService implements OnDestroy {
  subsc: Subscription;
  constructor(private auth: AngularFireAuth, private db: AngularFireDatabase, private fnc: AngularFireFunctions, private router: Router, private tostr: ToastrService) {

    this.subsc = this.auth.authState.subscribe((user) => {
      if (user) {
        this.db.database.ref("users/" + user.uid + "/shopCart/").on("value", snap => {
        });
      } else {
        // Not a user
      }
    });
  }

  ngOnDestroy(): void {
    console.log("Closed");
    this.subsc.unsubscribe();
    this.db.database.ref("users/" + this.currentUserId + "/shopCart/").off();
  }
}

Answer №1

According to @nate-kumar, Angular does not trigger the ngOnDestroy life cycle hook when the user closes the browser.

To work around this issue, you can implement the following solution:

export class AppComponent {
  @HostListener('window:unload', [ '$event' ])
  unloadHandler(event) {
    // perform necessary actions here
  }

  @HostListener('window:beforeunload', [ '$event' ])
  beforeUnloadHandler(event) {
    // perform necessary actions here
  }
}

You can view a functioning example on StackBlitz here.

Answer №2

ngOnDestroy does not get called when a browser window is closed. It only gets triggered when a component, service, or directive is destroyed while the Angular application is still running.

If you want to execute certain logic when the browser window is closed, one workaround is to use the onbeforeunload event on the window object:

Check out this Stack Overflow thread for more details: ngOnDestroy not firing on page reload

Answer №3

By default, Angular services do not utilize ngOnDestroy, but...

If you implement ngOnDestroy in a service, you can connect it to a component's ngOnDestroy.

This means that when the component is destroyed, the service's ngOnDestroy will also be called.

This feature is particularly useful for unsubscribing or removing data when it is no longer needed.

To link a service's ngOnDestroy to a component's ngOnDestroy, add the service to the component providers and implement ngOnDestroy in the service.

@Component({
  selector: 'app-test',
  templateUrl: './app-test.component.html',
  styleUrls: ['./app-test.component.scss'],
  providers: [YourService],
})

You can also refer to this resource regarding cases where ngOnDestroy may not fire on page reload.

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

Issue with parsing string data from API call in Angular (Web Core 3)

Controller code: [Route("api/[controller]")] [ApiController] public class CustomController : ControllerBase { ApplicationDbContext dbContext = null; public CustomController(ApplicationDbContext ctx) { dbContext = ctx; } ...

Transferring a JSON file between components within Angular 6 utilizing a service

I have been facing an issue in passing the response obtained from http.get() in the displayresults component to the articleinfo component. Initially, I used queryParams for this purpose but realized that I need to pass more complex data from my JSON which ...

Issue with Displaying Local Server Image in Angular 2 HTML

I am facing an issue with my Angular 2 Application. It retrieves items from a local database where the server stores the image of the item and the database stores the path to that image stored on the server. While I can retrieve all the items without any p ...

able to utilize service within a loop

import { Component, Input, Output, OnInit, OnChanges } from '@angular/core'; import { ViewComponent } from '../view/view.component'; import { HitoService } from '../../services/hito.service'; @Component({ selector: 'ap ...

Having trouble retrieving the default selected value using the index in Angular Material's mat-button-toggle functionality

I'm encountering an issue with setting the default value for a toggle button group. The code is simple and the toggle buttons are correctly fetching values from the index, but I can't seem to get one of them to be default selected. I tried settin ...

Using numerous maps within Ionic applications with the JavaScript SDK

Currently, I am utilizing the Google Maps (Javascript SDK) in Ionic V3 and have successfully created two pages with map views. Interestingly, while the first page displays the map correctly, upon opening the second page, the map shows up with grey lines, ...

Exploring the functionality of CanDeactiveGuard and ModalDialogService through unit testing

In my application, the CanDeactiveGuard is functioning properly. During unit testing, I encountered an issue with one test where I intended to use callThrough to invoke the openConfirmDialog() method within the Guard. This method triggers the Modal Dialog ...

The unit test ends right before reaching the RxJS skipWhile method

of({loadstatus: Loaded}) .skipWhile(user => user.loadStatus !== Loaded) .take(1) .subscribe(user => do some stuff) I am puzzled by why a unit test is not triggering the skipWhile function in the code snippet above. When I set a breakpoin ...

Encountering an error in TypeScript: Attempting to define type files for a third-party library triggers the TS2709 error when attempting to use the 'Optional' namespace as a type

Currently, I'm in the process of creating type files for a third-party library called optional-js. The structure is as follows: index.js var Optional = require('./lib/optional.js'); module.exports = { empty: function empty() { ...

Google Chrome does not display Set-Cookie header on page loads

Issue Having trouble with the Set-Cookie header not showing up in the response headers when making a request to a Spring Boot server's Post endpoint from an Angular app in Chrome's dev console. Summary of Findings Set-Cookie does appear in res ...

A more efficient way to specify children types in Typescript React is by directly specifying the type in the function instead

What is the reason behind this: interface UserSidebarProps { children? : React.ReactNode } function UserSidebar({children}: UserSidebarProps) { return ( <div> {children} </div> ) } Why doesn't this work? function User ...

Having trouble displaying ng-bootstrap toast using an interceptor or constructor in any Angular component. However, it functions properly when triggered by a button click

Is there a way to display toast notifications using an interceptor in Angular? I have a function in my toastService that works perfectly fine when called in a component, and even within the interceptor, the toasts array gets filled. However, the toast noti ...

Issues arise when trying to implement Angular class and it does

I'm currently facing some challenges using classes in Angular to simplify my coding process. So far, I haven't been able to get it to work properly. Below is the code snippet I'm working with and the error message that pops up: import { Wiz ...

assign data points to Chart.js

I have written a piece of code that counts the occurrences of each date in an array: let month = []; let current; let count = 0; chartDates = chartDates.sort() for (var i = 0; i < chartDates.length; i++) { month.push(chartDates[i].split('-&ap ...

Named functions in Typescript within functional components are the best practice for improving

How can I implement handleFoo using MyType['foo']? type MyType { foo: () => void } const Comp: React.FunctionComponent<{}> = () => { function handleFoo() {} return ... } I'm looking for a solution that doesn't inv ...

Instance of exported class declared in Typescript

Currently, I am in the process of developing my initial declaration file for a foreign library known as react-native-background-timer. Within this library, there exists a default export that I am uncertain about how to declare within the index.d.ts file. ...

The value binding for input elements in Angular 4 remains static and does not reflect changes in the UI

Struggling with binding input to a value in angular 4? Take for example [value]="inputFrom". Sometimes it updates when I change inputFrom, other times it doesn't. How can I ensure the input always changes whenever inputFrom changes, not sporadically? ...

What steps can be taken to troubleshoot and resolve this specific TypeScript compilation error, as well as similar errors that may

I am struggling with this TypeScript code that contains comments and seems a bit messy: function getPlacesToStopExchange(): { our: { i: number; val: number; }[]; enemy: { i: number; val: number; }[]; //[party in 'our' | 'enemy' ]: ...

Is the relevance of Angular 1.x still prevalent in today's development landscape

Considering I have several projects in angular 1.x, I'm contemplating whether it's truly essential and efficient to upgrade them to angular 4 or a later version. The smaller dashboards do not necessarily require an update since they are only use ...

Creating a Record instance consisting of a specific key and its corresponding value

Sorry for the complexity, I've struggled to simplify this further. Feel free to update the question title for more specificity. I aim to define a foundational data type structure: type AbstractBaseTypes = { [key: string]: { inputTypes ...