12

I'm having a strange issue where my HTML page isn't updating when the angular component variable changes. After pressing a button I do a network load and start playing audio like so:

onPreviewPressed(media: Media): void {
    if (this.playing) {
        this.playing = false;
        this.source.stop();
    }

    this.loading = true;

    this.service.downloadAudio(this.gender, this.style, this.ageRange, media).subscribe(abuf => {
        this.context.decodeAudioData(abuf, buffer => {
            this.source.buffer = buffer;
            this.playing = true;
            console.info(`Playing is ${this.playing}`);
            this.source.start(0);
        }, y => {
            console.info('Error: ' + y);
        });
        this.loading = false;
    }, () => {
        this.loading = false;
    });
}

And then on my HTML I have this snippet:

Playing is {{ playing }}
<button [hidden]="!playing" style="width: 44px; height: 44px" (click)="onStopPressed()">
    <img src="/assets/stop.png" alt="Stop">
</button>

When I click the button the audio properly downloads and starts playing, and in the console I see it say Playing is true but the HTML continues to say false, and doesn't show the button.

I thought it might be an issue of this not really being the component but the window variable, but if that were the case then the audio would really be able to play either as the source variable is part of the component.

2
  • Can you show us the code that calls onPreviewPressed? Commented Oct 20, 2018 at 16:06
  • using hidden is actually not recommended blog.angularjs.org/2016/04/… Commented Oct 20, 2018 at 16:13

3 Answers 3

17

I had a similar problem and fixed it by:

#Inject ChangeDetectorRef to the constructor
 constructor(private changeDetectorRef: ChangeDetectorRef)

ngOnInit(): void {
  # get data or listen to changes
  # then 
  this.changeDetectorRef.detectChanges();
}

Remember to import it by:

import { ChangeDetectorRef } from '@angular/core';
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! It can happen when the variable is updated inside an event listener. It'll be outside the Angular change detector.
6

Possible cause

It looks like the playing is not being capture as a part of change detector mechanism in Angular.

Fix : You have a couple of choices

The first is to use setters and getters for the playing variable

Functions always play a vital role as part of change detector so it ensures that your change in variable reflects.

In *.ts

get playingValue(){
    return this.playing;
}

set playingValue(playing){
    this.playing = playing;
}

In *.html

Playing is {{ playingValue }}

The second option is to use setTimeout(...)

this.service.downloadAudio(this.gender, this.style, this.ageRange, media).subscribe(abuf => {
        this.context.decodeAudioData(abuf, buffer => {
            this.source.buffer = buffer;

            setTimeout(()=>this.playing = true);  //setTimeout
            
            console.info(`Playing is ${this.playing}`);
            this.source.start(0);
        }, y => {
            console.info('Error: ' + y);
        });
        this.loading = false;
    }, () => {
        this.loading = false;
    });

Comments

0

Have you tried this:

<button *ngIf="playing" style="width: 44px; height: 44px" (click)="onStopPressed()">
    <img src="/assets/stop.png" alt="Stop">
</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.