What we want to do is call an endpoint from a url which returns 2 variables which can be used on multiple sections on the site. Although we are using the http call and subscribing to it, in order to speed up the site we only want to make the api call once. In order to do this we have created an Observable on the a service. Service calls a function in the constructor which sets the values of the Observable, however sometimes when visiting a link directly a cannot subscribe to method of undefined is returned. This is using the Microsoft ADAL library example code is below:
Firstly we are setting the variable as an Observable in the service:
@Injectable()
export class MicrosoftGraphService {
public details: Observable<any>;
Then we are setting the observable values in the constructor:
constructor(
private _http:Http,
private _adalService: AdalService,
private _sanitizer:DomSanitizer
) {
this.getToken().subscribe(token => {
/**
* Get me data from graph to determine school_id and mis_id
*/
this.get('me', token, true).subscribe(me => {
this.details = new Observable(observer => {
observer.next({
me: me
});
observer.complete();
});
});
});
The getToken function is:
getToken(): Observable<any> {
return this._adalService
.acquireToken( this._adalService.config.endpoints.graph );
}
The get function is:
get( endpoint, token, beta = false ): Observable<any> {
return this._http.get( this._adalService.config.endpoints.graph +
this.getVersion( beta ) + endpoint, {
headers: new Headers({ "Authorization": "Bearer " + token })
})
.map(res => {
return res.json();
});
}
This is then called in the constructor of the component as follows:
this._microsoftGraph.details.subscribe(details => {
console.log(details);
});
This should add a console log of the return of the me endpoint, however on certain pages it does and others it returns a cannot subscribe to undefined. The MicrosoftGraphService is called and set in the constructor on both pages correctly.
I am wondering if this happens because of the way it's called and when it's set e.g. the visiting the base url would call the parent component, as the MicrosoftGraphService is called in that constructor it is initialised first, so is available when visiting the second component through navigation. However going directly to the URL location for the child component might mean it's called first before the parent, even though both load the MicrosoftGraphService.
Example of the routes if it helps:
const routes: Routes = [
{
path: '',
component: SiteComponent,
canActivate: [LoggedInGuard],
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'tasks', component: TasksComponent },
{
path: '',
redirectTo: '/dashboard'
, pathMatch: 'full'
// , terminal: true
}
]
},