cup_of
cup_of

Reputation: 6687

Subscribing to ngrx store fires multiple times

I have a app with a ngrx store set up. I'm subscribing to it to get data from the store in a function that fires on a button click, I am getting the data I want, but every time I fire the function, it seems to return multiple copies of the data and when I fire it again, it grows exponentially.

So in my component.ts I have my selector that is connected to the store to fetch my data:

this.data$ = this.store.pipe(select(selectors.dataSelector));

Then my function that fires on click (in my html)

  onClick() {
     this.data$.subscribe(x =>
       console.log(x)
     );
   }

So after one iteration:

enter image description here

After two:

enter image description here

After three:

enter image description here

And so on. Why is this happening or is there a different way to get data from the store in the component.ts? I need it to return the data only once or else the performance will suffer greatly.

Upvotes: 5

Views: 8055

Answers (1)

Sergio Alen
Sergio Alen

Reputation: 724

Cos you're subscribing to data$ every time you click. If you want to do that onClick maybe unsubscribe after you console.log(x) or use rxjs take():

  onClick() {
     this.data$.pipe(take(1)).subscribe(x =>
       console.log(x)
     );
   }

From the docs:

Why use take

When you are interested in only the first set number of emission, you want to use take. Maybe you want to see what the user first clicked on when he/she first entered the page, you would want to subscribe to the click event and just take the first emission.

https://www.learnrxjs.io/operators/filtering/take.html

But my suggestion would be that you subscribe to the store somewhere else, like in your component constructor:

constructor(store) {
   store.pipe(select(selectors.dataSelector)).subscribe(x => {
       this.componentX = x;
   });
}

then simply on click you can see the data like this:

onClick() {
   console.log(this.componentX);
}

This way, you only subscribe once when the component gets initialised.

One more thing about subscriptions and how to prevent memory leak is to always unsubscribe when the component gets destroyed.

https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/

Upvotes: 7

Related Questions