Reputation: 6687
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:
After two:
After three:
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
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