I have the following classes:
import {Http, Response} from "@angular/http";
import {ErrorService} from "./error.service";
import {PreloaderService} from "./preloader.service";
import {Observable} from "rxjs/Observable";
@Injectable()
export class LoaderService {
constructor(protected http: Http,
protected errorService: ErrorService,
protected preloaderService: PreloaderService) {}
private sendPost(url: string, body: any): Observable<Response> {
this.preloaderService.show();
return this.http.post(url, body)
.map((r: Response): Response => {
this.preloaderService.hide();
return r;
})
.catch((e: any): any => this.errorService.handleError(e));
}
}
import {LoaderService} from "./loader.service";
@Injectable()
export class CollectionService extends LoaderService {
loadChunk(params: ILoaderParams) {
return this.sendPost(params.createEndpointUrl("/loadChunk"), params.getBody())
.map(r => <ILoadChunkResult>r.json());
}
}
import {LoaderService} from "./loader.service";
@Injectable()
export class AnimationsService extends LoaderService {
loadAnimationInfo(ownerId: string, ownerType: string): Observable<IAnimationInfo> {
const body = { ownerId, ownerType };
return this.sendPost("/animations/load-info", body)
.map(r => <IAnimationInfo>r.json());
}
}
Until 17.04.2020 it was all building and working fine, but after I've reinstalled all npm modules on 17.04.2020, calling loadAnimationInfo
started to break with an error: Cannot read property 'show' of undefined
. Calling loadChunk
was still working fine though.
What helped was to add super constructor call to AnimationsService
:
import {LoaderService} from "./loader.service";
import {Http} from "@angular/http";
import {ErrorService} from "./error.service";
import {PreloaderService} from "./preloader.service";
@Injectable()
export class AnimationsService extends LoaderService {
constructor(protected http: Http,
protected errorService: ErrorService,
protected preloaderService: PreloaderService) {
super(http, errorService, preloaderService);
}
loadAnimationInfo(ownerId: string, ownerType: string): Observable<IAnimationInfo> {
const body = { ownerId, ownerType };
return this.sendPost("/animations/load-info", body)
.map(r => <IAnimationInfo>r.json());
}
}
I would really like to know what could be the logic behind this behaviour?
UPD:
import {Injectable} from "@angular/core";
import {BusService} from "./bus.service";
@Injectable()
export class PreloaderService {
private requestCount: number = 0;
constructor(private busService: BusService) {
}
show() {
if (this.requestCount > 0) {
return;
}
this.requestCount++;
this.busService.emitPreloaderIsVisible(true);
}
hide() {
this.requestCount--;
if (this.requestCount > 0) {
return;
}
this.requestCount = 0;
this.busService.emitPreloaderIsVisible(false);
}
}
UPD2: all other injected services were as well undefined in the AnimatonsService
UPD3: i've managed to figure out, that it was an initialized private variable, that broke everything. AnimationsServer actually looks like:
export class AnimationsService extends LoaderService {
private _running:boolean = true;//it was not used, so I didnt pay attention on it at first
...
}
which leads to the following code in JS:
function AnimationsService() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._running = true;
return _this;
}
and (this is still a mystery to me!) to the following definition in the module.ngfactory.js
:
Object.defineProperty(AppModuleInjector.prototype, '_AnimationsService_79', { get: function() {
var self = this;
if ((self.__AnimationsService_79 == null)) { (self.__AnimationsService_79 = new jit_AnimationsService97()); }
return self.__AnimationsService_79;
}});
No dependencies are injected!
If I remove the initialization of the variable (but I still can leave the declaration private _running:Boolean;
), the JS result looks different:
function AnimationsService() {
return _this = _super !== null && _super.apply(this, arguments) || this;
}
and so is the definition:
Object.defineProperty(AppModuleInjector.prototype, '_AnimationsService_79', { get: function() {
var self = this;
if ((self.__AnimationsService_79 == null)) { (self.__AnimationsService_79 = new jit_AnimationsService97(self._Http_57,self._ErrorService_66,self._PreloaderService_65)); }
return self.__AnimationsService_79;
}});
Hope this will help to bring some light.