最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 8 => Condition : show an else value - Stack Overflow

programmeradmin0浏览0评论

I'm trying to filter a default value if no result is found on my query.

I tried using ng-template, but I simply don't manage to do it.


Rather than writing, here are images to better understand :

This is my successful filter : it correctly shows my datas once I filter them in the search box.


However if I try to enter an invalid data as done below :

It simply returns me an empty html table.

Which is not what I'd like to achieve. I'd like it instead to show a message saying : no data found.

How can I do it please?


And here is my source code :

Component :

import {Component, OnInit} from '@angular/core';
import {IProduct} from './product';

@Component({
  selector: 'pm-products',
  templateUrl: './product-listponent.html',
  styleUrls: ['./product-listponent.css']
})

export class ProductListComponent implements OnInit {

  ///////////////////////////////////// PROPERTIES //////////////////////////////////////

  // String Interpolation
  pageTitle = 'Product List';

  // Property binding
  imageWidth = 50;
  imageMargin = 2;

  // Event binding
  showImage = false;

  // Two-way binding
  // listFilter = 'cart';

  // Filter products
  private _listFilter: string;

  // Filter Products Array
  filteredProducts: IProduct[];

  ///////////////////////////////////// CONSTRUCTOR //////////////////////////////////////

  constructor() {
    this.filteredProducts = this.products;
    this.listFilter = 'cart';
  }

  /////////////////////////////////// GETTERS/SETTERS ///////////////////////////////////

  get listFilter(): string {
    return this._listFilter;
  }

  set listFilter(value: string) {
    this._listFilter = value;
    /***
     * If there is a list of filtered value, show the list of the filtered values => this.performFilter(this.listFilter)
     * Else, (if there is no filtered) return the whole set of products
     */
    this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
  }

  /////////////////////////////////////// METHODS ///////////////////////////////////////

  // Get Products
  products: IProduct[] = [
    {
      productId: 2,
      productName: 'Garden Cart',
      productCode: 'GDN-0023',
      releaseDate: 'March 18, 2019',
      description: '15 gallon capacity rolling garden cart',
      price: 32.99,
      starRating: 4.2,
      imageUrl: 'assets/images/garden_cart.png'
    },
    {
      productId: 5,
      productName: 'Hammer',
      productCode: 'TBX-0048',
      releaseDate: 'May 21, 2019',
      description: 'Curved claw steel hammer',
      price: 8.9,
      starRating: 4.8,
      imageUrl: 'assets/images/hammer.png'
    },
  ];

  performFilter(filterBy: string): IProduct[] {
    /**
     * filterBy result => to lower case. => case insensitive parison.
     * Return a new array of the filtered productS by the product name,
     * by checking if that product name given is an index of the an element in the product array.
     */
    filterBy = filterBy.toLowerCase(); // 1.
    return  this.products.filter((product: IProduct) => product.productName.toLowerCase().indexOf(filterBy) !== - 1); // 2.
  }

  toggleImage = (): void => {
    this.showImage = !this.showImage;
  }

  ////////////////////////////////// LIFECYCLE HOOKS ///////////////////////////////////

  ngOnInit(): void {
    console.log('hello');
  }
}

HTML

<div class="card">

  <div class="card-header">{{pageTitle}}</div>

  <!-- CARD -->
  <div class="card-body">
    <div class="row">
      <div class="col-md-2"> Filter by:</div>
      <div class="col-md-4">
        <input [(ngModel)]="listFilter" type="text"/>
      </div>
    </div>
    <div class="row">
      <div class="col-md-6">
        <h4>Filtered by: {{listFilter}} </h4>
      </div>
    </div>
    <!-- ./CARD -->

    <!-- TABLE -->
    <div class="table-responsive">
      <table *ngIf="products && products.length" class="table">
        <thead>
        <tr>
          <th>
            <button (click)="toggleImage()" class="btn btn-primary">{{showImage ? "Hide" : "Show"}} image</button>
          </th>
          <th>Product</th>
          <th>Code</th>
          <th>Available</th>
          <th>Price</th>
          <th>5 Star Rating</th>
        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let product of filteredProducts">
          <td><img *ngIf="showImage" [src]="product.imageUrl" [title]="product.productName"
                   [style.width.px]="imageWidth" [style.margin.px]="imageMargin" alt=""></td>
          <td>{{product.productName}}</td>
          <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
          <td>{{product.releaseDate}}</td>
          <td>{{product.price | currency: 'EUR':'symbol':'2.2-2'}}</td>
          <td>{{product.starRating}}</td>
        </tr>
        </tbody>
      </table>
    </div>
    <!-- ./TABLE -->
  </div>
</div>

Please take care of yourself.

I'm trying to filter a default value if no result is found on my query.

I tried using ng-template, but I simply don't manage to do it.


Rather than writing, here are images to better understand :

This is my successful filter : it correctly shows my datas once I filter them in the search box.


However if I try to enter an invalid data as done below :

It simply returns me an empty html table.

Which is not what I'd like to achieve. I'd like it instead to show a message saying : no data found.

How can I do it please?


And here is my source code :

Component :

import {Component, OnInit} from '@angular/core';
import {IProduct} from './product';

@Component({
  selector: 'pm-products',
  templateUrl: './product-list.ponent.html',
  styleUrls: ['./product-list.ponent.css']
})

export class ProductListComponent implements OnInit {

  ///////////////////////////////////// PROPERTIES //////////////////////////////////////

  // String Interpolation
  pageTitle = 'Product List';

  // Property binding
  imageWidth = 50;
  imageMargin = 2;

  // Event binding
  showImage = false;

  // Two-way binding
  // listFilter = 'cart';

  // Filter products
  private _listFilter: string;

  // Filter Products Array
  filteredProducts: IProduct[];

  ///////////////////////////////////// CONSTRUCTOR //////////////////////////////////////

  constructor() {
    this.filteredProducts = this.products;
    this.listFilter = 'cart';
  }

  /////////////////////////////////// GETTERS/SETTERS ///////////////////////////////////

  get listFilter(): string {
    return this._listFilter;
  }

  set listFilter(value: string) {
    this._listFilter = value;
    /***
     * If there is a list of filtered value, show the list of the filtered values => this.performFilter(this.listFilter)
     * Else, (if there is no filtered) return the whole set of products
     */
    this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
  }

  /////////////////////////////////////// METHODS ///////////////////////////////////////

  // Get Products
  products: IProduct[] = [
    {
      productId: 2,
      productName: 'Garden Cart',
      productCode: 'GDN-0023',
      releaseDate: 'March 18, 2019',
      description: '15 gallon capacity rolling garden cart',
      price: 32.99,
      starRating: 4.2,
      imageUrl: 'assets/images/garden_cart.png'
    },
    {
      productId: 5,
      productName: 'Hammer',
      productCode: 'TBX-0048',
      releaseDate: 'May 21, 2019',
      description: 'Curved claw steel hammer',
      price: 8.9,
      starRating: 4.8,
      imageUrl: 'assets/images/hammer.png'
    },
  ];

  performFilter(filterBy: string): IProduct[] {
    /**
     * filterBy result => to lower case. => case insensitive parison.
     * Return a new array of the filtered productS by the product name,
     * by checking if that product name given is an index of the an element in the product array.
     */
    filterBy = filterBy.toLowerCase(); // 1.
    return  this.products.filter((product: IProduct) => product.productName.toLowerCase().indexOf(filterBy) !== - 1); // 2.
  }

  toggleImage = (): void => {
    this.showImage = !this.showImage;
  }

  ////////////////////////////////// LIFECYCLE HOOKS ///////////////////////////////////

  ngOnInit(): void {
    console.log('hello');
  }
}

HTML

<div class="card">

  <div class="card-header">{{pageTitle}}</div>

  <!-- CARD -->
  <div class="card-body">
    <div class="row">
      <div class="col-md-2"> Filter by:</div>
      <div class="col-md-4">
        <input [(ngModel)]="listFilter" type="text"/>
      </div>
    </div>
    <div class="row">
      <div class="col-md-6">
        <h4>Filtered by: {{listFilter}} </h4>
      </div>
    </div>
    <!-- ./CARD -->

    <!-- TABLE -->
    <div class="table-responsive">
      <table *ngIf="products && products.length" class="table">
        <thead>
        <tr>
          <th>
            <button (click)="toggleImage()" class="btn btn-primary">{{showImage ? "Hide" : "Show"}} image</button>
          </th>
          <th>Product</th>
          <th>Code</th>
          <th>Available</th>
          <th>Price</th>
          <th>5 Star Rating</th>
        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let product of filteredProducts">
          <td><img *ngIf="showImage" [src]="product.imageUrl" [title]="product.productName"
                   [style.width.px]="imageWidth" [style.margin.px]="imageMargin" alt=""></td>
          <td>{{product.productName}}</td>
          <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
          <td>{{product.releaseDate}}</td>
          <td>{{product.price | currency: 'EUR':'symbol':'2.2-2'}}</td>
          <td>{{product.starRating}}</td>
        </tr>
        </tbody>
      </table>
    </div>
    <!-- ./TABLE -->
  </div>
</div>

Please take care of yourself.

Share Improve this question asked Aug 21, 2019 at 20:08 Finalmix6Finalmix6 4159 silver badges23 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Maybe just include an *ngIf="!filteredProducts.length" wherever you'd like to show your message.

ex.


<tr *ngFor="let product of filteredProducts">
    //Your table stuff
</tr>
<tr *ngIf="!filteredProducts.length">
     <td colspan="6">No data found</td>
</tr>

You have to add tr contains string no data found after ngfor tr

  <tr *ngFor="let product of filteredProducts">
          <td><img *ngIf="showImage" [src]="product.imageUrl" [title]="product.productName"
                   [style.width.px]="imageWidth" [style.margin.px]="imageMargin" alt=""></td>
          <td>{{product.productName}}</td>
          <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
          <td>{{product.releaseDate}}</td>
          <td>{{product.price | currency: 'EUR':'symbol':'2.2-2'}}</td>
          <td>{{product.starRating}}</td>
        </tr>

<tr *ngIf="filteredProducts.length === 0 " >
<td colspan="6" >Your message here </td>
</tr>

You can simply add a row that appears only when the list is empty and the search bar has any value. like this:

 <tr *ngFor="let product of filteredProducts">...</tr>

 <tr col-span ="6" *ngIf="!filteredProducts.length && listFilter.length"> uh oh, 
 could not find what you searched for</tr>

发布评论

评论列表(0)

  1. 暂无评论