Having a Component that loads user data and needs to handle direct access via URL, I implemented a resolver service in the router. It works fine when accessing the component through routing within the application. But upon refreshing the page with the URL, the resolver service throws this error:
ERROR Error: "Uncaught (in promise): TypeError: this.userService.getCurrentUser() is undefined
It seems like the userService isn't initialized quickly enough during refresh.
Here's the code for the resolver service:
@Injectable({
providedIn: 'root'
})
export class UserResolverService {
constructor(private userService: UserService, private authService: AuthService, private router:Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> | Observable<never> {
let id = route.paramMap.get('id');
//return this.authService.checkToken().subscribe(res => {
if(this.authService.checkToken()){
return this.userService.getCurrentUser().pipe(take(1), mergeMap(user => {
if(user){
return of(user);
} else {
this.router.navigate['/login'];
return EMPTY;
}
}));
} else {
this.router.navigate['/login'];
return EMPTY;
}
}
}
This is the method called in UserService:
getCurrentUser(): Observable<User>{
if(this.currentUser.value != null){
return this.currentUser.asObservable().pipe(filter(user => user != null));
} else {
this.setCurrentUser().subscribe(res => {
return this.currentUser.asObservable().pipe(filter(user => user != null));
})
}
The setCurrentUser() method calls the backend with credentials to retrieve user data.
The constructor of the Component that should load its data upon refreshing contains the following:
this.route.data.subscribe((data: {user: User}) => {
this.user = data.user;
this.initialDialogWindows();
this.initialViewGuidingVariables();
});
EDIT:
I updated it with the solution from Aakash Garg. Now, the ngOnit() methods only receive undefined and the resolver doesn't wait for promises. None of the console logs other than "am I even here?" are executed.
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> {
let id = route.paramMap.get('id');
//return this.authService.checkToken().subscribe(res => {
if(this.authService.checkToken()){
console.log("am I even here?");
this.userService.getCurrentUserPromise().then(user => {
console.log("resolved user:" + user);
if(user){
return of(user);
} else {
console.log("navigating to login");
this.router.navigate['/login'];
return EMPTY;
}
});
} else {
console.log("navigating to login, because there is no token");
this.router.navigate['/login'];
return EMPTY;
}
}