Reputation: 646
I am using Ionic with Angular under the hood.
Setup
"@angular/router": "~9.1.9",
"@ionic/angular": "^5.1.1",
"rxjs": "^6.5.5",
I use the following login method: When it's triggered the spinner is shown, data is loaded, routed to another page and then the spinner gets hid again.
loginWithGoogle() {
this.showSpinner = true;
this.authService.getAuthSessionPersistence()
.pipe(
concatMap(() => this.authService.getAuth().signInWithPopup(new auth.GoogleAuthProvider())),
concatMap(() => this.databaseService.getUserModel()
.pipe(
concatMap(userModel => {
if (Object.keys(new UserInit()).every(key => userModel[key])) {
return of(userModel).pipe(first());
}
return this.authService.getUser()
.pipe(
concatMap(user => this.databaseService.createUser(user.uid, userModel))
);
}),
concatMap(userModel => this.store.dispatch([
new SaveUserAction(userModel),
new LoadFixturesAction(),
new LoadTeamsAction(),
new LoadTransactionsAction(),
])
),
tap(() => this.router.navigateByUrl('tabs/home'))
)),
finalize(() => this.showSpinner = false)
)
.subscribe();
}
The problem is that the spinner is hid earlier than the routing has happened. The user sees for a short moment again the login screen which is not very user friendly.
As you see in the code above: The last RxJS operator is use finalize
which is where the spinner gets hid.
Do you know why the router takes long to navigate?
Upvotes: 0
Views: 1529
Reputation: 646
Thx to answers we managed to find a solution.
Mistakes
tap(() => this.router.navigateByUrl('tabs/home'))
Solution
concatMap(() => from(this.router.navigateByUrl('tabs/home')))
Upvotes: 1
Reputation: 96959
I think you can concatMap
into the chain another Observable with NavigationEnd
event right before finalize()
.
...
concatMap(() => this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
)),
finalize(() => this.showSpinner = false),
This way the chain will be disposed (and finalize
triggered) only after the next NavigationEnd
event.
Upvotes: 1
Reputation: 9235
I am not too familiar with rxjs operators myself, but the router.navigateByUrl method that you have returns a promise according to: https://angular.io/api/router/Router#navigateByUrl
This means your code can hide spinner after such promise is resolved:
...
tap(() => this.router.navigateByUrl('tabs/home').then(()=>{
this.showSpinner = false
})
)
...
Upvotes: 1