0

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.

  • include also whats inside of your `PreloaderService` here – John Velasquez Apr 17 '20 at 19:49
  • It is hard to say without seeing all the details how your services are used, if they provided once or not and so on. On the snippets you posted I am surprised it worked before, since using inheritance you have to have all the injected deps in the derived class' constructor and pass them to the parent via `super`. Please take a look at [this question](https://stackoverflow.com/questions/39038791/inheritance-and-dependency-injection) – Shlang Apr 17 '20 at 19:50
  • @Shlang yes, the snippets are probably not enough, but the codebase is pretty big, and I just dont know, what else can be importaint. I can say that the `CollectorService` is being injected a lot throughout the code, and the `AnimationsService` is injected only 2 times. Both are stated in the `providers` section of `NgModule`. About passing deps to the super class: I just dont implement contsructors in the derived classes explicitly, so they just use the parent constructor. I'm pretty sure it is a valid syntax: https://www.logicbig.com/tutorials/misc/typescript/class-inheritance.html – Nikolay Kana Apr 18 '20 at 12:06
  • @JohnVelasquez added the code to the original post – Nikolay Kana Apr 18 '20 at 12:11

1 Answers1

1

it seem a known bug

Someone suggest a workaround but it leads to bigger bundles

changing the compilerOptions.target property to es5 in tsconfig.json

Radik
  • 2,715
  • 1
  • 19
  • 24