Reputation: 3246
I have an Angular app with an auth service where i'm handling the user state like so -
@Injectable()
export class AuthService extends HttpService<User> {
private readonly _user: BehaviorSubject<User>;
public user$: Observable<User>;
constructor(http: HttpClient) {
super(http, 'users');
this._user = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('user')));
this.user$ = this._user.asObservable();
}
signIn(email: string, password: string): Observable<User> {
return this.http.post<User>(this.path + '/login', { email: email, password: password})
.pipe(map(user => {
if (user && user.token) {
localStorage.setItem('token', user.token);
localStorage.setItem('user', JSON.stringify(user));
this._user.next(user);
}
return user;
}));
}
}
Now this in my sign in component this works fine and the user is successfully returned -
export class SignInComponent {
constructor(private auth: AuthService, private router: Router) { }
signIn(email: string, password: string): void {
this.auth.signIn(email, password).subscribe(user => {
this.loading = false;
this.router.navigate(['/pages/dashboard']);
}, error => {
this.failed = true;
this.loading = false;
});
}
}
However in the component I'm redirected to after the sign in the user observable is null -
export class DashboardComponent implements OnInit {
constructor(
private authService: AuthService,
) { }
ngOnInit() {
this.authService.user$.subscribe(user => {
console.log(user); // <- the user here is null!
})
}
}
If I refresh the browser the user object is successfully returned.
I assumed you could share data this way between components but it appears this isn't the case. How would I achieve this?
I should also say the sign in and dashboard components are in different modules.
Upvotes: 1
Views: 280
Reputation: 14679
However in the component I'm redirected to after the sign in the user observable is null
probably because its ngOnInit
runs after user$
emitted. You need a ReplaySubject, not a BehaviorSubject.
BTW, you can replace your map
.pipe(map(user => {
if (user && user.token) {
//...
with tap
, will make the return
statement unnecessary.
Upvotes: 1