captain
captain

Reputation: 1827

How can I return a message when I get no results from my filter?

I have set up page that shows different products. I've made a search box with a ng-model="query" and whenever I type my query the page gets automatically updated to the products that I have.

The problem is that whenever the query doesn't match something the page stays blank and this doesn't look good. Instead of a blank page I want the site to display a message saying along the lines of "No products found". How can I achieve this?

I've looked at other questions and their solutions but they didn't work.

Here is my code for the way the products are displayed. As you can see I've added a ng-show="products.length === 0 as some solutions suggested but the message never appears when I don't have a match.

        <ul class="list-group">
        <li ng-repeat="product in products | filter:query" class="list-group-item">
            <h3><a id="productName" href="#/products/{{product.name}}">{{ product.name }}</a></h3>
            <img id="mainImage" ng-src="{{ product.imgUrl }}" alt="{{ product.name}}">
            <p id="description"> {{ product.description }}</p>
            <p id="price"> Price: {{ product.price }} £</p>
            <p ng-show="products.length === 0">Nothing found</p>
        </li>
    </ul>

Here is my controller code for the products page:

//Controller that fetches the available products to display them in the view
app.controller('productListController', function($scope, $http){
$http.get('products/products.json').success(function(data){
    $scope.products = data.products;
    });
});

Here is the code for the search box:

<div id="searchbox">
        <div class="input-group">
        <input type="text" class="form-control" ng-model="query" placeholder="Search for...">
            <span style="width=1%;" class="input-group-btn">
              <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-search"></span></button>
            </span>
        </div><!-- /input-group -->
        </div><!-- searchbox -->

Upvotes: 0

Views: 93

Answers (2)

Stepan Kasyanenko
Stepan Kasyanenko

Reputation: 3186

The answer @Daniel is not entirely correct.

As you ng-repeat to use a filter, this filter must also be applicable to the condition of ng-show.

Like this:

<ul> 
 <li ng-repeat="product in products | filter:query" class="list-group-item">
  <h3><a id="productName" href="#/products/{{product.name}}">{{ product.name }}</a></h3>
  <img id="mainImage" ng-src="{{ product.imgUrl }}" alt="{{ product.name}}">
  <p id="description"> {{ product.description }}</p>
  <p id="price"> Price: {{ product.price }} £</p>
 </li>
</ul>
<p ng-show="products && (products| filter:query).length === 0">Nothing found</p>

Live example on jsfiddle.

angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope) {
    $scope.search = {};
    $scope.arr = [];
    $scope.isLoaded = false;
    $scope.load = function() {
    $scope.isLoaded = true;
      $scope.arr = [{
        x: 1
      }, {
        x: 2
      }, {
        x: 3
      }, {
        x: 11
      }, {
        x: 12
      }];
    };
    $scope.clear = function() {
      $scope.isLoaded = false;
      $scope.arr = [];
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController">
    <input ng-model="search.x">
    <button ng-click="load()">
      Load array
    </button>
    <button ng-click="clear()">
      Clear array
    </button>
    <div ng-repeat="a in arrFiltered = (arr|filter:search)">
      {{a.x}}
    </div>
    <div ng-show="isLoaded && arrFiltered.length==0">
      not found
    </div>

  </div>
</div>

Upvotes: 0

Daniel
Daniel

Reputation: 6481

Take the <p ng-show="products.length === 0">Nothing found</p> outside the ng-repeat.

<li ng-repeat="product in filteredProducts = (products | filter:query)" class="list-group-item">
    <h3><a id="productName" href="#/products/{{product.name}}">{{ product.name }}</a></h3>
    <img id="mainImage" ng-src="{{ product.imgUrl }}" alt="{{ product.name}}">
    <p id="description"> {{ product.description }}</p>
    <p id="price"> Price: {{ product.price }} £</p>
</li>
<p ng-show="filteredProducts.length === 0">Nothing found</p>

It doesn't show because the ng-repeat is empty.

EDIT:

In order to be sure that the msg is displayed after products data is loaded:

$http.get('products/products.json').success(function(data){
       $scope.products = (data.products && data.products.length > 0) ? data.products : [];
    });
});

Upvotes: 3

Related Questions