Reputation: 1195
I'm trying to inject a HttpService into my CoreModule. This works in the ngOnInit
function but when I try to access the services in an other function the service becomes undefined.
Component
export class TreeComponent implements OnInit {
constructor(private store: Store<AppState>,
private cdRef: ChangeDetectorRef,
private injector: Injector,
private locationService: LocationService) { }
async ngOnInit() {
await this.store.pipe(
select('auth'),
map(async (authState) => {
if (authState.isAuthenticated) {
console.log(this.locationService);
this.data.push(await this.injector.get(LocationService).getBaseLocation().toPromise());
this.cdRef.detectChanges();
console.log(this.locationService);
}
})
).toPromise();
}
/* Ommited where not used */
public hasChildren(node: any): boolean {
console.log(node);
console.log(this.locationService); <-- undefined
console.log(this.injector); <-- undefined
//Check if the parent node has children.
return true;
}
CoreModule
@NgModule({
declarations: [ShellComponent, SidebarComponent, TreeComponent],
imports: [
CommonModule,
RouterModule,
SharedModule,
TreeViewModule,
FormsModule
],
exports: [
],
providers: [AuthService, Shell, LocalizationService, LocationService]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new Error(`${parentModule} has already been loaded. Import Core module in the AppModule only.`);
}
}
}
App Module
@NgModule({
declarations: [
AppComponent
],
imports: [
HttpClientModule,
BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createCustomTranslateLoader),
deps: [HttpClient]
},
missingTranslationHandler: {
provide: MissingTranslationHandler,
useClass: CreateMissingTranslationHandler,
deps: [HttpClient]
},
useDefaultLang: true
}),
StoreModule.forRoot(reducers, { metaReducers }),
!environment.production ? StoreDevtoolsModule.instrument({
maxAge: 25 // Retains last 25 states
}) : [],
EffectsModule.forRoot([AuthEffects]),
CoreModule,
SharedModule,
ProductionOverviewModule,
AppRoutingModule,
BrowserAnimationsModule
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: (initI18n),
deps: [
HttpClient,
TranslateService,
],
multi: true
},
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
LocationService
const headers = new HttpHeaders({
'Content-Type': 'application/json'
});
@Injectable()
export class LocationService {
public currentPlant: BehaviorSubject<Location>;
constructor(private http: HttpClient) {
this.currentPlant = new BehaviorSubject<Location>(null);
}
getBaseLocation(): Observable<Location> {
return this.http.get<Location>(environment.API_BASE_URI + '/Location/GetBaseLocation', { headers: headers })
.pipe(map(location => {
this.currentPlant.next(location);
location.childeren = [];
return location;
}));
}
getChildLocations(locationId: string): Observable<Location[]> {
return this.http.get<Location[]>(environment.API_BASE_URI + `/Location/GetLocationTree?upperLocationID=${locationId}`, { headers: headers })
.pipe(map(location => {
return location;
}));;
}
}
I tried multiple things like importing the service in the app module, trying to assign the service to a variable,.. but it stays undefined. Hopefully someone can point me in the right direction.
Upvotes: 0
Views: 866
Reputation: 194
This is because the "hasChildren" function gets called from kendo-treeview component, it is required you bind the current context to the function before passing it.
Changing
[hasChildren]="hasChildren"
To
[hasChildren]="hasChildren.bind(this)"
Will do the trick
Upvotes: 2
Reputation: 1160
Supposing the hasChildren
function is called from the kendo-treeview
component in your HTML, you should use the Function.prototype.bind function:
<kendo-treeview
kendoTreeViewExpandable
[nodes]="data"
textField="text"
[children]="fetchChildren"
[hasChildren]="hasChildren.bind(this)">
^^^^^^^^^^^^^^^^^^^^^^
</kendo-treeview>
What happens here is when hasChildren
is being executed, the scope is different and so the this
is not what you expected.
The bind
function returns a new function that is bound to the this
you defined.
Upvotes: 2