Angular show different divs based on search input and on no input

Issue

Hello 🙂 I am making a search in my Angular 14 + Ionic v6 app and have made a search field so the user can search for products. The search is an API call. I have now three scenarios that I’d like to achieve.

  1. The user is on the search page and has not entered any text in the search so there is a div bellow the search input field that shows "Enter atleast 3 characters to search…"

  2. The second one is if the userhas searched for something but there were no results. I want to display a div with text: "Your search did not find any results…"

  3. Show search results -> THIS WORKS

So how do I show the two other divs? They are now both vissible at the same time… What have I done wrong in my code?

HTML markup:

  <ion-searchbar inputmode="search" [debounce]="1000" placeholder="Iskanje" show-clear-button="focus" (change)="search($event)"></ion-searchbar>
  <ion-list>
    <ion-item *ngIf="products.length === 0" class="ion-text-center">
      <ion-label>
        <span class="prod-code">Enter atleast 3 characters to search...</span>
      </ion-label>
    </ion-item>
    <ion-item routerLink="/product/{{produkt.id}}" *ngFor="let produkt of products">
      <ion-label>
        <span class="prod-code">{{ produkt.product_code }}</span>
        <span class="prod-name">{{ produkt.name }}</span>
      </ion-label>
    </ion-item>
    <ion-item *ngIf="products.length === 0" class="ion-text-center">
      <ion-label>
        <span class="prod-code">Your search did not find any results...</span>
      </ion-label>
    </ion-item>
  </ion-list>

TS code for search api call:

import { Component, OnInit } from '@angular/core';
import { SearchService } from '../services/search.service';
import { ToastController } from '@ionic/angular';

@Component({
  selector: 'app-search',
  templateUrl: './search.page.html',
  styleUrls: ['./search.page.scss'],
})
export class SearchPage implements OnInit {
  term: string;
  products: any = [];
  // searchResult: SearchResult;

  constructor(
    private searchService: SearchService,
    private toastController: ToastController,
  ) { }

  ngOnInit() {

  }

  search(event: any) {
    console.log('Searched value = ' + event.target.value);
    const searchTerm = event.target.value;
    if(searchTerm === '') {
      return this.products = [];
    } else {
      this.searchService.searchByTermCall(searchTerm).subscribe(
        (data: any) => {
          console.log(data.body);
          this.products = data.body;
        },
        error => {
          console.log('Error', error);
        }
      );
    }
  }

  async errorToast(message, position: 'bottom') {
    const toast = await this.toastController.create({
      message,
      duration: 3000,
      color: 'danger',
      icon: 'close-circle-outline',
      position
    });
    await toast.present();
  }

}

Solution

You can use nested ngIf, if your products array is undefined before first search event, if not you need to change first ngIf logic according to the search bar value.

<ion-searchbar inputmode="search" [debounce]="1000" placeholder="Iskanje" show-clear-button="focus" (change)="search($event)"></ion-searchbar>
<ion-list>
   <ion-item *ngIf="!products; else searched" class="ion-text-center">
      <!-- Enter at least 3 characters.. -->
   </ion-item>
   <ng-template #searched>
      <ion-item *ngIf="products.length !== 0; else emptyList" class="ion-text-center">
         <!-- Render products with ngFor.. -->
      </ion-item>
      <ng-template #emptyList>
         <!-- No result.. -->
      </ng-template>
   </ng-template>
</ion-list>

Answered By – tmsbrndz

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published