Please note: I know there is
APP_INITIALIZER
but this seems to work only on the top-level module (app.module.ts) of the application.
I have as parent component which loads some data:
In admin-area.component.ts:
ngOnInit(): void {
forkJoin([
this._userService.getMe(),
this._placeService.getAll()
])
.pipe(finalize(() => this.afterInit()))
.subscribe(
([user, businesses]) => {
this._appState.user = user;
this._appState.businesses = businesses;
this.afterInit();
}
);
}
The problem is that there are child components which rely on this._appState.user
and this._appState.businesses
.
I cannot load this with APP_INITIALIZER
because the above data is only loaded, if the user is logged in. The "logged-in" area is a lazy-loaded module on it own.
So, the question is rather simple:
How can I make sure my data is loaded before child components try to display themselves?
This:
providers: [
AdminAreaState,
{ provide: APP_INITIALIZER, useFactory: adminAreaInit, deps: [AdminAreaState], multi: true}
]
Does not work. adminAreaInit()
is not getting called. This only works for my top-level module app.module.ts. So, APP_INITIALIZER
does not seem to work on any other module, is that corrent?
What are my options here?
I think I need to provide some more details.
Note, that I am already trying to use *ngIf
:
<div *ngIf="!business?.servicePlan">
Please Upgrade
</div>
but the problem is that if I navigate to this particular page and refresh the page, business
is always undefined
. business
is a result of finding the right business
in the Array of businesses
using the businessId
.
At the time the child component gets loaded, I load additional data. In this case some reviews (comments).
Now, loadPage()
loads one page of my requrested data for a business. _appState
is a service which is supposed to be loaded first. If I do this:
private loadPage() {
console.log(this._appState);
console.log(this._appState.businesses);
this._appState.businesses.forEach(
(b) => {
console.log(b);
});
setTimeout(() => this._appState.businesses.forEach(
(b) => {
console.log(b);
}
), 100);
const businessId = this._appState.businessId;
this.business = this._appState.businesses.find(b => b.id === businessId);
}
This is what I get:
As you can see this._appState
has businesses but this._appState.businesses
does print an empty array.
_appState.businesses
is just an Observable
:
ApplicationState
service:
@Injectable()
export class ApplicationState {
public businessIdChange;
public businessesChange;
private _user = new BehaviorSubject<UserModel>(null);
private _businessId = new BehaviorSubject<number>(null);
private _businesses = new BehaviorSubject<Array<BusinessModel>>([]);
constructor() {
this.businessIdChange = this._businessId.asObservable();
this.businessesChange = this._businesses.asObservable();
}
set user(value: UserModel) {
this._user.next(value);
}
get user(): UserModel {
return this._user.getValue();
}
set businessId(businessId: number) {
if (businessId === this.businessId) {
return;
}
this._businessId.next(businessId);
}
get businessId() {
return this._businessId.getValue();
}
set businesses(value) {
this._businesses.next(value);
}
get businesses(): Array<BusinessModel> {
return this._businesses.getValue();
}
}
I have no idea why I see this and I thought pre-loading the data would make sense anyway. But maybe I have a different issue here?