I'm using ngxs State management. Do I need to unsubscribe from Selectors or is this handled by ngxs?
@Select(list)list$!: Observable<any>;
this.list$.subscribe((data) => console.log(data));
Specifically, we must unsubscribe before Angular destroys the component. Failure to do so could create a memory leak. We unsubscribe from our Observable in the ngOnDestroy method.
Effects are the primary way of handling logic within NgRx. They allow us to observe streams of actions and react to them. We do not need to subscribe to any effect nor do you need to manually unsubscribe. That is handled internally by the NgRx Effects module; once again taking that burden out of our hands.
NGXS is a state management pattern and library for Angular. NGXS acts as a single source of truth for your application's state - providing simple rules for predictable state mutations. NGXS is modeled after the CQRS pattern - a pattern implemented in state management libraries such as NgRx and Redux.
One method we can use, is to unsubscribe manually from active subscriptions when we no longer require them. RxJS provides us with a convenient method to do this. It lives on the Subscription object and is simply called . unsubscribe() .
For the first example you can use in combination with the Async pipe. The Async pipe will unsubscribe for you:
In your ts
file:
@Select(list) list: Observable<any>;
In your html
file:
<ng-container *ngFor="let item of list | async">
</ng-container>
<!-- this will unsub automatically -->
However, when you want to use the actual subscribe method, you will need to unsubscribe manually. Best way to do that is using takeUntil
:
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
@Component({
selector: 'app-some-component',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.scss']
})
export class SomeComponent implements OnInit, OnDestroy {
private destroy: Subject<boolean> = new Subject<boolean>();
constructor(private store: Store) {}
public ngOnInit(): void {
this.store.select(SomeState).pipe(takeUntil(this.destroy)).subscribe(value => {
this.someValue = value;
});
}
public ngOnDestroy(): void {
this.destroy.next(true);
this.destroy.unsubscribe();
}
}
You can use pipe(takeUntil(this.destroy))
for every subscription in your component without the need to manually add unsubscribe()
for every one of them.
The Async Pipe solution is usually the best.
Depending on your use case, you can also use the first() operator.
observable.pipe(first()).subscribe(...)
It is shorter than the takeUntil approach and you don't need any unsubscribe.
https://www.learnrxjs.io/operators/filtering/first.html
Beware: This will return a value and unsubscribe. So it can be used if you need a current value from the store and then do something with it. Don't use it to display something on the GUI - it will only show the first change :)
Yes, if you subscribe manually in the component then you need to unsubscribe.
Best to avoid that if possible and subscribe in the component template using the async
pipe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With