How to show a message about filtering and loading data in Async Pipe Angular?

84 Views Asked by At

I need your help. I have a piece of code with the help of which I get characters from the API and with the help of input, I search for my characters.

Also, I'm trying to show a message in my html that if I didn't find anything during the search for my characters, I saw the message: no items found, and when I load data at start and during the search, the message was displayed: Loading.

The problem is that my message No items found is always displayed. even when the application has just started and the Loading message is not displayed at all. Please help me, where is my problem? Thank you very much

HTML

<div *ngFor="let character of (characters | async)">
  {{ character.name }}
</div>

<div *ngIf="loading">
  Loading...
</div>

<div *ngIf="!response.length && !loading">
  No items found
</div>

Typescript

public characters: Observable<DifferentCharacter[]>;
public loading: boolean = false;
public response: DifferentCharacter[] = [];

public gettingAndInputCharacters(): void {
const inputSearchItem = localStorage.getItem('inputCharacterValue') || '';

const filterCharacters = (value: string) => {
  return this.charactersService.getAllCharacters(value).pipe(
    map((response) => {
      const characters = response.results.sort((a, b) => {
        return a.name.localeCompare(b.name);
      });
      return value ? characters.filter((character: DifferentCharacter) => {
        const name = character.name.trim().toLowerCase();
        const searchInputItem = value.trim().toLowerCase();
        return name.startsWith(searchInputItem) ||
          searchInputItem.split('').every((char: string, index: number) => char === name.charAt(index));
      }) : characters;
    }),
    catchError(() => of([]))
  );
};

this.form.controls['searchCharacterInput'].setValue(inputSearchItem);

this.form.controls['searchCharacterInput'].valueChanges.subscribe(value => {
  this.loading = true;
  localStorage.setItem('inputCharacterValue', value);
  this.characters = filterCharacters(value).pipe(finalize(() => this.loading = false));
  this.characters.subscribe(value => {
    this.response = value
  })
});

  this.characters = filterCharacters(inputSearchItem);
}
1

There are 1 best solutions below

4
Nikita On

First, avoid to use the same name for class variable and variable which you use in function. For example response as class variable and in map((response)

This

this.characters = filterCharacters(inputSearchItem);

looks odd, because earlier you added

this.characters = filterCharacters(value).pipe(finalize(() => this.loading = false));

and instead of

<div *ngIf="!response.length && !loading"> 

use

<div *ngIf="!(characters | async)?.length && !loading">

and

const characters = response.results.sort((a, b)

return type {name: string}[]. Not DifferentCharacter[]. It might be a reason of you general issue

Demo https://stackblitz.com/edit/angular-4fre3k?file=src/main.ts