Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8 using ngIf with async pipe to show and hide the HTML element

I am trying to show and hide HTML elements according to the service result. I am using *ngIf="messageService.getData() | async" but it isn't working to show or hide the element. I am using async, otherwise "Failure Message" is shown for a short time and then "Successful Message" is shown.

I have 2 tags like these:

<div *ngIf="messageService.getData() | async">Successful Message</div>
<div *ngIf="!messageService.getData() | async">Failure Message</div>

In the service I have a code like this:

export class MessageService {
  constructor(private http: HttpClient) { }

  public getData() {
    return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
    .pipe(
      map((response) => {
        console.log("success");
      }),
      catchError(this.handleError)
    )
  }

  private handleError(error: Response) {
    console.log("handleError")
    let errMsg: string;
    errMsg = "error"
    return Observable.throw(errMsg);
  }
}

Here is the source code: https://stackblitz.com/edit/angular-iqr6az

like image 854
nanokozmos Avatar asked Dec 31 '22 14:12

nanokozmos


2 Answers

in your service:

public getData() {
    return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
    .pipe(
      map((response) => {
        return response; // return res
      }),
      catchError(this.handleError)
    )
  }

in your component:

export class MessageComponent implements OnInit {
  isServiceAPIWorking: boolean;
  todos;
  loadingError$ = new Subject<boolean>();
  constructor(private messageService: MessageService) { }

  ngOnInit() {
    this.todos = this.messageService.getData().pipe(
      catchError((error) => {
        // it's important that we log an error here.
        // Otherwise you won't see an error in the console.
        console.error('error loading the list of users', error);
        this.loadingError$.next(true);
        return of();
      })
    );
  }
}

in your html:

<div>Show Message:</div>
<div *ngIf="todos | async">Successfull Message</div>
<div *ngIf="loadingError$ | async">Failure Message</div>

DEMO 🚀🚀.

like image 178
Fateme Fazli Avatar answered Jan 03 '23 05:01

Fateme Fazli


Why bother with async pipes when you can just assign the data in your component?

// message.component.ts

class MessageComponent implements OnInit {
  isServiceAPIWorking: boolean;
  data: any;
  constructor(private messageService: MessageService) { }

  ngOnInit() {
    this.messageService.getData()
      .subscribe(response => {
        this.isServiceAPIWorking = true;
        // Assign the data
        this.data = response;
      },
        error => {
          this.isServiceAPIWorking = false;
        })
  }
}
// message.component.html

<div>Show Message:</div>
<div *ngIf="data">Successfull Message</div>
<div *ngIf="!data">Failure Message</div>

And there is a mistake in your service. If you use map without returning anything, you won't get any data in the end. Use tap if you want to do logging:

// message.service.ts

public getData() {
  return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
  .pipe(
    tap((response) => {
      console.log("success");
    }),
    catchError(this.handleError)
  )
}

Updated Stackblitz

like image 20
frankie567 Avatar answered Jan 03 '23 05:01

frankie567