Search code examples
singletonangular5angular-aot

How to provide service inside the component in angular 5 with aot?


I have met the error

question-images.service.ts(5,2): Error during template compile of 'QuestionImagesService' Only initialized variables and constants can be referenced in decorators because the value of this variable is needed by the template compiler in 'Injectable' 'Injectable' references 'Injectable' 'Injectable' references 'Injectable' 'Injectable' is not initialized at ..\@angular\core\src\di\metadata.ts(138,22)

This is component

import { Component, OnChanges, OnInit } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';
import { QuestionImagesService } from '@app/patient/components/assesment/questions/question-images.service';
import { QuestionBase } from '@app/patient/components/assesment/questions/question.base';

@Component({
  selector: 'ez-slider-question',
  templateUrl: './slider-question.component.html',
  styleUrls: ['./slider-question.component.scss'],
  providers: [QuestionImagesService]
})
export class SliderQuestionComponent extends QuestionBase implements OnInit, OnChanges {
  minValue: number;
  maxValue: number;
  value: number;
  smallStep: number;
  imageId = 0;
  images: { [key: number]: SafeHtml } = {};

  constructor(private questionImagesService: QuestionImagesService) { super(); }

  ngOnInit() {
    this.minValue = 1;
    this.smallStep = 1;
    this.maxValue = this.question.answers.length;
    this.value = this.question.userAnswers[0]
      ? Number(this.question.answers.find(answer => answer.id === this.question.userAnswers[0].id).value)
      : this.minValue;
    this.images = this.questionImagesService.startLoadingImages(this.question);
  }

  getNewUserAnswerValues(): string[] {
    return [this.value.toString()];
  }

  onValueChange(value: number) {
    this.imageId = this.question.answers.find(answer => answer.value === value.toString()).id;
  }

This is service

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core/src/core';
import { SafeHtml, DomSanitizer } from '@angular/platform-browser';

@Injectable()
export class QuestionImagesService {
    private images: { [key: number]: SafeHtml } = {};

    constructor(private httpClient: HttpClient, private domSanitizer: DomSanitizer) { }

    startLoadingImages(question: IQuestion): { [key: number]: SafeHtml } {
        this.images = {};
        question.answers.forEach(answer => {
            if (answer.imageUrl) {
                this.httpClient.get(`http://localhost:54531/${answer.imageUrl}`, { responseType: 'text' })
                    .subscribe(imageHtml => this.images[answer.id] = this.domSanitizer.bypassSecurityTrustHtml(imageHtml));
            }
        });
        return this.images;
    }
}

The error has been thrown during execution of ng serve --aot. I've tried to google and to use service factory, but without success. I want to provide service in such way, because I want to have one instance of it per component. Have you any idea how to achive this?


Solution

  • The problem is that you are importing Injectable from the wrong path inside QuestionImagesService. Change the import to:

    import { Injectable } from '@angular/core';