2

I am trying to get the value of a string variable explanationText from my QuizService to display in my di-quiz component template using data-binding. console.log is showing undefined for explanationText and data-binding to the template isn't displaying anything for explanationText when an answer is selected. Please see: https://stackblitz.com/edit/angular-9-quiz-app

Any idea why this is not working? Please can you help. Thank you!

In my quiz.service.ts file, I have:

@Injectable({providedIn: 'root'}) {
  export class QuizService {
  explanationText: string;
  ...

  setExplanationAndCorrectAnswerMessages() {
    this.question = this.getQuestion;
    if (this.question) {
      if (this.correctAnswers.length === 1) {
        this.explanation = ' is correct because ' + this.question.explanation + '.';
      }
      if (this.correctAnswers.length > 1) {
        this.explanation = ' are correct because ' + this.question.explanation + '.';
      }
    }

    if (this.correctAnswers && this.correctAnswers.length === 1) {
      const correctAnswersText = this.correctAnswers[0];
      this.explanationText = 'Option ' + correctAnswersText + this.explanation;
      console.log(this.explanationText);
      this.correctAnswerMessage = 'The correct answer is Option ' + this.correctAnswers[0] + '.';
      console.log(this.correctAnswerMessage);
    }
    if (this.correctAnswers && this.correctAnswers.length > 1) {
      if (this.correctAnswers[0] && this.correctAnswers[1]) {
        const correctAnswersText = this.correctAnswers[0] + ' and ' + this.correctAnswers[1];
        this.explanationText = 'Options ' + correctAnswersText + this.explanation;
        console.log(this.explanationText);
        this.correctAnswerMessage = 'The correct answers are Options ' + correctAnswersText + '.';
        console.log(this.correctAnswerMessage);
      }
      ...
    }
  }

In my di-quiz.component.ts, I have a getter/setter and constructor as follows:

get explanation(): string { return this.quizService.explanationText; };
@Input() set explanation(value: string) { this.explanationText = value; };

constructor(private quizService: QuizService,
            private timerService: TimerService,
            private route: ActivatedRoute) {
  this.explanationText = this.explanation;
  console.log("ExpTxt: " + this.explanationText);
}

and in my di-quiz.component.html, I have

<section id="question" [class.answered]="answer">
  <span *ngIf="!answer">{{ question?.questionText }}</span>
  <span *ngIf="answer">{{ explanationText }}</span>
</section>
9
  • 2
    first try to initialize the explanationText in your service Commented Apr 5, 2020 at 1:36
  • In the code above explanationText is uninitialized. How are you initializing it in QuizService? Commented Apr 5, 2020 at 1:44
  • I am setting the explanationText in the setExplanationAndCorrectAnswerMessages() function (see above). Commented Apr 5, 2020 at 14:17
  • I have tried the following code but still not able to get it to work: @Input() set explanationTextVal(value) { this.explanationText = value; }; ngOnChanges(changes: SimpleChanges) { if (changes.explanationTextVal && changes.explanationTextVal.currentValue !== changes.explanationTextVal.firstChange) { this.explanationText = changes.explanationTextVal.currentValue; } } Commented Apr 7, 2020 at 22:52
  • @multiv123 You have posted an enormous stackblitz that is extremely hard to follow. There is so much wrong with the design that a simple answer here is not going to solve your problem - you need to redesign the whole project. Did you base your project on this github.com/marvinrusinek/codelab-quiz? Commented Apr 8, 2020 at 15:46

2 Answers 2

2
+50

I check your stackblitz code and found the issue. Its because you are registering your QuizService in DependencyInjectionQuizComponent and QuestionComponent, which creates multiple instace.

So when question component fires setExplanationAndCorrectAnswerMessages it update explanationText in different instance but your DIQuizComponent expect from different instance.

To fix this you have to remove QuizService from QuestionComponent providers.

I have forked and updated the code. Here is the link

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Didn't think it was so simple. I'm looking at the code. I'll need to make similar change for correctAnswerMessage.
It seems that it only shows the explanationText if the answer is correct, otherwise the question box is empty.
You need to check logic or conditions how you are displaying it. I didn't check.
2

Change above constructor like this,

constructor(
  private quizService: QuizService,
  private timerService: TimerService,
  private route: ActivatedRoute
  ) {
     this.explanation = 'Text you want';
     this.explanationText = this.explanation;
     console.log("ExpTxt: " + this.quizService.explanationText);
}

1 Comment

I need the value of explanationText determined by the setExplanation function in my service.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.