Is it safe to use takeWhile in Angular 12 with RxJS without implementing onDestroy?

I'm a bit confused about how to use takeWhile.

Here's what I'm trying to achieve:

  • Wait for the Observable fireAuthUser$ to emit a value
  • Once it emits a value, perform some actions
  • If fireAuthUser$ doesn't emit a value, cancel when the component is destroyed
export class AuthService implements OnDestroy {
    fireAuthUser: BehaviorSubject<firebase.User | undefined> = new BehaviorSubject<firebase.User | undefined>(undefined);
    public readonly fireAuthUser$: Observable<firebase.User | undefined> = this.fireAuthUser.asObservable();
    private subscription?: Subscription;

    constructor(public fire: AngularFireAuth) {
        this.subscription = this.fire.authState.subscribe((fireAuthUser) => {
            if (fireAuthUser) {
                this.fireAuthUser.next(fireAuthUser);
                // ...
            }
        });
    }

    ngOnDestroy(): void {
        this.subscription?.unsubscribe();
    }

    doSomeStuff(): void {
       //do some stuff
    }

}
export class Foo implements OnInit {

    constructor(public auth: AuthService) { }

    ngOnInit(): void {
         this.auth.fireAuthUser$.pipe(takeWhile((fireAuthUser) => fireAuthUser === undefined)).subscribe({
          complete: () => this.auth.doSomeStuff()
        });
    }

}

The code above seems to work, but there's a concern raised in this Stack Overflow post about using takeWhile and unsubscribing. The suggestion is to manually set a value on ngOnDestroy, but doing so might erase the existing fireAuthUser object. What should be done in this scenario?

Answer №1

Utilize the takeUntil Operator to monitor this.auth.fireAuthUser$ until the current component is destroyed.

import { Subject, takeUntil } from 'rxjs';

export class Foo implements OnInit{
  private destroy$ = new Subject();
  constructor() {}

  ngOnInit(): void {
    this.auth.fireAuthUser$
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (data) => console.log(data),
        complete: () => this.uponComplete(),
      });
  }

  uponComplete() {
    console.log('Finally completed');
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.complete();
  }
}

View a demonstration here (click on Go to Auth timer will start and click on Home it will unsubscribe)

Answer №2

Implement the takeUntil operator. I enjoy developing a custom BaseComponent that inherits from a class with observables.

@Component({
    template: ''
})
export abstract class BaseComponent implements OnDestroy {
    protected unsubscribe: Subject<void> = new Subject();

    ngOnDestroy(): void {
        this.cleanUp();
    }

    private cleanUp(): void {
        this.unsubscribe.next();
        this.unsubscribe.complete();
    }
}

By extending from this base class, you can utilize the takeUntil method to handle observable cleanup when the component is destroyed.

export class LeadEditComponent extends BaseComponent implements OnInit {
    ngOnInit(): void {
         this.subscription = this.fire.authState
            .pipe(
                 takeUntil(this.unsubscribe)
             )
            .subscribe((fireAuthUser) => {
                if (fireAuthUser) {
                    this.fireAuthUser.next(fireAuthUser);
                    // ...
                }
         });
    }
}

Answer №3

Instead of manually unsubscribing, why not utilize the ngOnDestroy lifecycle hook?

export class Bar implements OnInit {

    private subscription: Subscription;
    constructor(public authenticationService: AuthService) { }

    ngOnInit(): void {
         this.subscription = this.authenticationService.fireAuthUser$.pipe(takeWhile((fireAuthUser) => fireAuthUser === undefined)).subscribe({
          complete: () => this.authenticationService.doSomething()
        });
    }

    ngOnDestroy() {
      this.subscription.unsubscribe();
    }

}

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

Ways to merge two arrays into one in React JS

Here are two arrays presented below: const arrayA = { 0: { id: XXXXXXX, name: "test" }, 1: { id: YYYYYYY, name: "example" } } const arrayB = { 0: { id: XXXXXXX, category: "sea", } 1: { id: YYYYY ...

Applying REGEX on input text in React Native

I'm having trouble getting my regex function to work correctly, so I believe there might be an error in my code. Any assistance would be greatly appreciated. Here is the regex function I am using: let validatePlate = (plate) => { var re = /(^[A ...

Angular Customization

Seeking to incorporate a theme into my Angular (5) web app, I am using Angular Material for select components and input fields only. I am in need of a theming solution that allows me to manipulate, control, and change themes dynamically without the need to ...

Slim API receives a request from Ionic 5

Seeking assistance with making a GET request from my Ionic application to an API constructed using the Slim Framework. Below is the code snippet of the API: <?php header('Access-Control-Allow-Origin: *'); header('Content-Type: applicati ...

Applying styles to every tr element in Angular 2 components

I'm trying to use background-color with [ngClass] on a table row. The styles are being applied, but they're affecting all rows' backgrounds. I want the background color to only change for the specific row that is clicked. Here is my code: ...

Building a dynamic form in Angular that includes dynamic event binding and dynamic function execution

Hey there, I'm just starting out with angular and I'm looking to create a form that can render using JSON data which also includes events and functions. Here's the setup: <div *ngFor="let form of forms; index as i "> <div ...

Using TypeScript to work with JSON fields that include the '@' symbol

While working on an Angular project with TypeScript, I am facing a challenge of displaying certain JSON fields obtained from a POST request to the user. One of the fields begins with the '@' symbol, which is a reserved word in Angular causing th ...

Encountering a 404 error when trying to retrieve the Next.js 14 API route, despite specifying the use of route

Currently, I am working with Next.js version 14.2.3 and attempting to access the /api/tmp API route from the chat.tsx component. However, I keep encountering a 404 error even though I am using the route.ts file. What could be causing this issue? UPDATE: C ...

What is the best way to inform the user of their login status in Angular?

As a newcomer to angularfire2, I am currently working on implementing authentication and providing the user with feedback on their login status. I am using version angularfire2": "^5.0.0-rc.4. I came across an example on this site, but I am unsure of how i ...

The Angular 2 router encounters issues with reusing a Component instance when navigating to the same route with varying parameters

Based on the information provided in Angular 2 documentation: The default behavior of the router is to reuse a component instance when navigating to the same component type without visiting a different component first. However, the parameters may change ...

What are some ways to enhance the content within a JWT?

After following this tutorial, I am interested in adding additional information to the token. Specifically, I would like to include an 'accessRights' field that can be used for user authorization in both the backend and Angular. Where should I i ...

Include the circle.css file in the Angular 4 project by loading it in the head section of the

I am currently working with Angular 4 and would like to incorporate the circle.css styles from cssscript. After downloading the file from the provided link, I placed the circle.css within my something component file. However, when attempting to use &l ...

Using Pipes to Truncate Text in Angular 4 with PrimeNg

Is there a way to limit the output of a data-table to 150 characters? Here is the pipe I am using: transform(value: string, args: string[]): string { const limit = args.length > 0 ? parseInt(args[0], 10) : 20; const trail = args.length > 1 ...

Angular 10 carousel malfunction: unable to scroll images as intended

Recently, I attempted to integrate a bootstrap carousel into my angular web page. I copied the source code directly from the bootstrap site, so I assumed everything was configured correctly... Despite this, the carousel does not slide as expected. Additio ...

The file is missing the required fields in the Firestore document

I've been facing a challenge while attempting to update specific fields within a firebase document. Even though the cloud function triggers and performs an upload on the document, the values of the fields I am trying to update never seem to get upload ...

Guide for using two Async Pipe functions in Angular 7

Two different functions are in place to check a specific condition, and the requirement is for both of them to be true simultaneously. How can *ngIf be utilized to achieve this? Currently, setting just one of them works, but the aim is to have both. HTML ...

Steps for modifying the value of a field within an Angular formGroup

Is there a way to update the value of the "send_diagnostic_data" field in a separate function? private generateForm(): void { this.messageForm = new FormGroup({ message: new FormControl(''), date: new FormControl(new Date()), messag ...

The parameter type (key: string, id: string, pagination: number) in the argument does not match the expected type of Boolean for the parameter

I'm facing an issue while trying to implement the following documentation: https://swr.vercel.app/ using my own setup: import React, { useEffect } from 'react' import PatientsTable from 'components/patients/PatientsTable' import ...

Jest is raising a TypeError: Unable to access attributes of an object that is undefined (referencing 'getVideoTracks')

When running my unit tests with Jest, I encountered an error: TypeError: Cannot read properties of undefined (reading 'getVideoTracks') Does anyone have any suggestions on how to properly test the following line using Jest? [videoTrack] = (await ...

Taking out the modal element from the document object model, causing the animation

I am currently working on a project using Next.js, Typescript, and Tailwind CSS. Within this project, I have implemented a modal component with some animations. However, I encountered an issue where the modal does not get removed from the DOM when closed, ...