Andrew Howard
Andrew Howard

Reputation: 3082

Angular subscription allowed in ngOnInit?

In most of the tutorials I've been following, they say to always do a subscription within the constructor ie:

constructor(private eventDetailsService: EventDetailsService) {
      this.subscription1 = this.eventDetailsService.reload$
            .subscribe(
            response => {
                this.eventDetail = response;
            });
}

And then to destroy the subscription within ngDestroy:

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

I have a particular component where I need to do some logic within ngOnInit first to workout whether I need to call the subscription in the first place. It allows me to do the subscription within ngOnInit without any errors, but I was wondering if there is a consequence of doing this?

ngOnInit() {
   if ((this.activatedRoute.parent.snapshot.parent.params.eventId != undefined))
        {
            this.subscription1 = this.eventDetailsService.reload$
            .subscribe(
            response => {
                this.eventDetail = response;
            });
        }
}

Upvotes: 1

Views: 1553

Answers (2)

Quentin Fonck
Quentin Fonck

Reputation: 1315

Yes, it's good practice to subscribe in the onInit() method.
I would recommend to use your constructor only to declare your dependency injections.
In this particular case though, you might run into an error when you leave your component since there's a possibility that your subsciption equals undefined when you call on destroy (you put your code in a if statement). You can declare your params as an observable to prevent this:

    ngOnInit() {
        const eventId$ = this.route.parent.parent.params.pipe(
            map((params: Params) => params.get('eventId')),
            filter(id => !!id)
        );
        this.subscription = eventId$.pipe(
            mergeMap(() => this.eventDetailsService.reload$())
        ).subscribe(response => {
            this.eventDetail = response;
        });
    }

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

By doing so, your observable will only emit when you have the eventId param in your route and your subscription is safe to be unsubscribed once you destroy the component.
Also, If you navigate to the same component with a different eventId param, this observable will emit the new eventId value and retrigger your logic.

Upvotes: 2

Marek W
Marek W

Reputation: 729

It is even good practice to put your Subscriptions into the ngOnInit(), as you want to initialize the data as soon as possible and display data directly when you access the component and update the UI.

There are no consequences, as you already .unsubscribe() in your ngOnDestroy() step.

Upvotes: 2

Related Questions