I have an Ionic app with 2 parts. One main/home and a custom splash screen
I've made the splash to load all the config files and data that the main app will need. And has to be done before
Home starts.
Before this new attempt I used a function with an IF and many tests. This function is called every time a different file load, and its
respective flag changed until all flags are true, and Home page can load.
PRIOR SPLASH SCREEN
private initConfig() {
this.loadClasses();
this.loadNotes();
...
}
private loadClasses(){
this.configService.loadClasses()
.subscribe(data => {
//data process
this.lock.hasClasses = true;
this.checkConfigReadiness();
});
}
...
//Every other load method following the same pattern above
private checkConfigReadiness(){
if(
this.lock.hasClasses &&
this.lock.hasNotes &&
this.lock.hasKeywords &&
this.lock.hasLangs &&
this.lock.hasTypes &&
this.lock.hasUserAchievs &&
this.lock.hasUserCollection
){
//navigateHome
}
}
I wanted to try a more elegant solution with CanActivate guard, but I'm on a crossroad in which I don't know if what I want is possible or if its not possible at all or maybe my idea of how Guards work is completely wrong.
SPLASH NOW
ngOnInit() {
this.configService.isReady().subscribe(isReady => {
if (isReady) {
this.navCtrl.navigateRoot('/main/home');
}
});
this.initConfig();
}
private initConfig() {
this.configService.loadTypes();
...
}
CONFIG SERVICE
private lock: AccessLock = new AccessLock();
private isConfigReady: BehaviorSubject<boolean> = new BehaviorSubject(false);
private classes: BehaviorSubject<BaseConfigItem[]> = new BehaviorSubject([]);
...
isReady(): Observable<boolean> {
return this.isConfigReady.asObservable();
}
private checkConfigReadiness(){
if(
this.lock.hasClasses &&
this.lock.hasNotes &&
this.lock.hasKeywords &&
this.lock.hasLangs &&
this.lock.hasTypes &&
this.lock.hasUserAchievs &&
this.lock.hasUserCollection
){
this.isConfigReady.next(true);
} else {
this.isConfigReady.next(false);
}
}
loadClasses(): Promise<any> {
return this.getClassesFileJSON() //method return changed with .toPromise()
.then(data => {
this.classes.next(data);
this.lock.hasTypes = true;
this.checkConfigReadiness();
})
.catch(e => { throw e })
}
...
//Every other load method following the same pattern above
CONFIG CAN ACTIVATE GUARD
constructor(
private configService: ConfigService,
private navCtrl: NavController
) { }
canActivate(): Observable<boolean> | boolean {
const isReady = this.configService.isReady();
//ALWAYS TRUE HERE
if (isReady) {
return true;
}
this.navCtrl.navigateRoot('/splash');
return false;
}
APP ROUTING
const routes: Routes = [
{
path: 'main',
loadChildren: () => import('./pages/main/main.module').then(m => m.MainPagesModule),
canActivate: [ ConfigCanActivateGuard ]
},
{
path: 'splash',
loadChildren: () => import('./pages/splash/splash.module').then( m => m.SplashPageModule)
},
{
path: '',
redirectTo: 'splash',
pathMatch: 'full'
},
];
The situation now:
The app start loading the files, once every file is loaded the app progress to Home Page, Ok!
But if I reload the Home Page, the app don't go to Splash screen and restart the loading process to return Home. As I thought it should because of the CanActivateGuard..
Any clarification or adjustments on best practices?
====== Edition with a mofication on ConfigGuard =====
canActivate(): Observable<boolean> {
const isReady = this.configService.isReady();
isReady.subscribe(
isReady => {
if (isReady) {
return true;
}
this.navCtrl.navigateRoot('/splash');
return false;
},
error => {
console.log(error);
this.navCtrl.navigateRoot('/splash');
return false;
}
);
return isReady;
}
Now its working. If the app is on the Home page, it will navigate back to Splash and load the config as it needs.