Reputation: 740
I'd like to close a login dialog whenever the Firebase authState changes. I read online that I the subscribe()
function would cause data leaks if the unsubscribe()
function isn't called and therefore, want to replace the function. Here is my code:
this.user = this.auth.authState.pipe(
switchMap( (user) => {
if(user) {
return (this.firestore.collection('users').doc(user.uid).valueChanges() as Observable<User>)
} else {
return of(null);
}
})
);
I'd like to replace the subscribe
function here with something else:
this.authService.user.subscribe( (user) => {
if(user) {
this.isLoading = false;
this.dialogRef.close();
}
})
This is what I tried, but I think I'm using the map function incorrectly:
this.authService.user.pipe(
map( (user) => {
if(user) {
this.isLoading = false;
this.dialogRef.close();
}
})
)
Thanks in advance!
Upvotes: 0
Views: 581
Reputation: 71891
The subscribe
function in itself is not bad, or any memory leak. It becomes an issue when you do not unsubscribe the Subscription
or complete the Observable
when the component code or service code is destroyed.
But it all depends on what you want to do:
If this is a global listener in a root service. You do not have to care about it, because the life cycle of the service is the same as your entire app.
If it's a listener in a component, you need to make sure to unsubscribe from it when the component is destroyed:
@Component({...})
export class SomeComponent implements OnDestroy {
private destroy$ = new Subject<void>();
constructor(private authService: AuthService) {}
checkLogin(): void {
this.authService.user.pipe(
filter((user) => !!user),
takeUntil(this.destroy$)
).subscribe((user) => {
this.isLoading = false;
this.dialogRef.close();
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
Judging by your code it feels like you are using angular material as well, and you are actually waiting for a user to login. Then this would be the most appropriate solution:
@Component({...})
export class SomeComponent {
constructor(private authService: AuthService) {}
checkLogin(): void {
this.authService.user.pipe(
filter((user) => !!user),
take(1),
takeUntil(this.dialogRef.beforeClosed)
).subscribe((user) => {
this.isLoading = false;
this.dialogRef.close();
});
}
}
This unsubscribes when:
takeUntil(...)
AuthService
with a user by using filter(...)
and take(1)
And only in the second case will it reach the subscribed method
Upvotes: 1