2

I'm using a few REST services to gather data and then change the value of an Observable in my component code. I'm trying to use an *ngIf to show/hide div tags based on the result. However, it isn't working, the *ngIf is not updating based on the change to the Observable.

Do I have to trigger change detection? What's the best way to achieve this in Angular 7? Here's one example I tried:

HTML:

<div *ngIf="isAnimal$">
     <p>animal</p>
</div>

Component:

public isAnimal$: Observable<boolean> = of(false);
...
ngOnInit() {
  checkAnimal();
}

private checkAnimal() {
  this._dataService.getData()
      .subscribe((result) => {
         if (result === 'animal') {
           this.isAnimal$ = of(true);
         }
      });
}

I also tried creating a simple service and that didn't work either. Like this: Angular *ngIf binding to function

1 Answer 1

5

I suggest the following:

HTML:

<div *ngIf="isAnimal">
     <p>animal</p>
</div>

Component:

public isAnimal: boolean = false;

ngOnInit() {
  checkAnimal();
}

private checkAnimal() {
  this._dataService.getData().subscribe(
    (result) => {
       if (result === 'animal') {
         this.isAnimal = true;
       }
    },
    (error) => {
      console.log(error);
    }
 );
}

I am not sure, but I think you could use the async pipe instead using your implementation:

<div *ngIf="isAnimal$ | async">
     <p>animal</p>
</div>

The reason your solution is not working is because isAnimal$ is an observable that has to be resolved. The async pipe could do this, but I prefer the first solution to be honest. It does not seem natural to me to create another observable of(true) in your subscription.

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

5 Comments

that's the first approach I tried. I'm logging the result: "animal : true" but the *ngIf isn't changing the HTML. I suspect the *ngIf is not waiting for the async call to return. The async pipe doesn't work with a boolean.
@beachCode the first approach works for 100 %, the *ngIf automatically listens to the changes of the value that is passed, which is a boolean. The second approach should work as well. Don't forget that isAnimal$ is not a boolean here, it is an observable. When it is resolved, it should be a boolean.
I just noticed something weird. I am using interpolation to show some data ({{name}} and that isn't updating either.... weird. What's up with this component?
so the issue here seems to be an error that's caused by a Google API call. I couldn't see it initially but it appeared when I changed the component behaviour. The error appears to be causing the issues I'm seeming with interpolation and *ngif not working. Here's the first part of the error from the console: ERROR DOMException: Failed to execute 'querySelector' on 'Document': '#scope=openid email profile googleapis.com
You should always add error handling when you subscribe (see my edits above), this might help to find the issues. :)

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.