Reputation: 889
I'm working with a service that implements a global service called AppService
which stores some global app configurations.
To begin with my question, I will post here some of my codes:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector, APP_INITIALIZER } from '@angular/core';
import { AppService } from './app.service';
...
export function appLoadConfig(appService: AppService) {
return () => appService.loadConfig();
}
@NgModule({
imports: [
BrowserModule,
CoreModule,
...
],
declarations: [
AppComponent,
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: appLoadConfig,
deps: [ AppService ],
multi: true
}
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
app.service.ts
import { Injectable, ... } from '@angular/core';
...
@Injectable({
providedIn: 'root'
})
export class AppService {
loadConfig(): Promise<any> { ... }
}
file.service.ts
import { Injectable } from '@angular/core';
import { AppService } from '../../app.service';
...
@Injectable()
export class FileService {
filesChange: BehaviorSubject<FileNode[]> = new BehaviorSubject<FileNode[]>([]);
constructor(
private appService: AppService,
private httpClient: HttpClient) { }
changeListType(types: string[]) {
this._getAllFiles();
}
private _getAllFiles() {
this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
.subscribe(this._publishData);
}
private _publishData(data: FileNode[]) {
let nodeData: FileNode[] = [];
data.forEach((n: any) => {
const node = new FileNode(n);
node.fullPath = `${this.appService.config.api}/uploads/${node.uri}`;
nodeData.push(node);
});
this.filesChange.next(nodeData);
}
}
When in a component I call the changeListType
method from file.service
, it retrieves the data, but the _publishData
method shows that this.appService
, used to build the node.fullPath
, is undefined. If I change the call in the _getAllFiles
method subscriber to this one:
this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
.subscribe((data: any) => { this._publishData(data); });
The appService
variable is not undefined anymore. Is this on purpose or it is a kind of bug/error related with scope variables? Or maybe I'm missing something within my code logic.
Thanks in advance.
Upvotes: 0
Views: 290
Reputation: 3727
You have got a problem with the scope of this
:
In your second approach where you are not getting appService
as undefined because you are referencing _publishData
function from within an arrow function. Arrow functions doesn't create their own this
and uses the this from it's outer scope. When _publishData
function is being invoked in this case the this
which it is referencing is the this
of the component and not the function's this
Read more about arrow functions here.
If you are not using an arrow function and want to get the correct this
for the subscriber function you will need to bind the this
You need to bind the correct this to _publishData
function
private _getAllFiles() {
this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
.subscribe(this._publishData.bind(this));
}
Upvotes: 3