I have a header component which makes a call to fetch the user token and store the user's data. I then have a different component (admin component) that is not a child of the header which relies on the user data to fetch additional data. The issue I'm running into is that the admin component initializes before the header component has finished making it's call for the user, therefore breaking my admin component. In other words, the code execution breaks because the active company has not been set yet by the header. Is there a way to make sure these load synchronously in Angular 6 so that I can avoid this issue?
header.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
user: any;
activeCompany: any;
constructor(private authService: AuthService) { }
ngOnInit() {
this.authService.getToken().then((user) => {
this.user = user;
this.user.Companies = JSON.parse(this.user.Companies.split('"').join('"'));
this.authService.getActiveCompany$().subscribe((company: any) => {
if(!company) {
let company = this.user.Companies[0]
this.authService.setActiveCompany$(JSON.stringify(company));
}
this.activeCompany = company;
});
});
}
setActiveCompany(company) {
this.authService.setActiveCompany$(company)
}
}
admin.component.ts
import { Component, OnInit } from '@angular/core';
import { TagService } from '../../services/tag.service';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-admin',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.css']
})
export class AdminComponent implements OnInit {
companyId: number;
tags: any;
loading: boolean = true;
constructor(
private tagService: TagService,
private authService: AuthService
) {}
ngOnInit() {
this.authService.getActiveCompany$().subscribe((company: any) => {
// The line below breaks because the active company has not been set yet by the header
this.companyId = company.Id
this.tagService.getTags(companyId).then((tags) => {
this.setTags(tags)
this.loading = false;
});
});
}
}
auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { AppConfig } from '../../app-config';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private activeCompany$: Subject<any>;
constructor(private http: HttpClient, private _config: AppConfig) {
let initialActiveCompany;
if (window.localStorage.getItem('activeCompany')) {
initialActiveCompany = JSON.parse(window.localStorage.getItem('activeCompany'));
}
this.activeCompany$ = new BehaviorSubject<any>(initialActiveCompany);
}
getToken() {
return new Promise(resolve => {
this.http.get(`${this._config.API_URL}/Token`).subscribe(data => {
resolve(data);},
err => {
console.log("Error retrieving token", err);
});
});
}
// Returns the observable (read-only) part of this subject
getActiveCompany$(): Observable<any> {
return this.activeCompany$.asObservable();
}
// Stores the new company value in local storage and pushes it to the subject
setActiveCompany$(company: any) {
window.localStorage.setItem('activeCompany', JSON.stringify(company));
this.activeCompany$.next(company);
}
}
from How do I load components synchronously in Angular 6?
No comments:
Post a Comment