Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : How use $http in a filter

Tags:

angularjs

I would like to do a request to my backend in a filter and return the result of my request. The problem is the service $http return a promise and it's the issue.

For present the issue I used a $timeout and the promises of angular in my fiddle : my fiddle

In my filter I use a $timeout with a promise but the final goal is to use a request http :

myApp.filter('filterHello', function ($http,$timeout,$q) {
return function (company_id) {
    console.log("in the filter");
    var deferred = $q.defer();   
    $timeout(function() {
        deferred.resolve("ca marche");
    }, 2000);                  
    return deferred.promise;
};

});

Then in my view I use my filter who is suppose to display "ca marche" with a delay of 2 secondes but that doesn't work :

<div ng-controller="MyCtrl">
   {{hello|filterHello}}
</div>

You can see that the filter return nothing and that there is an infinite loop in the filter because of the null promise I think.

If you don't understand why I want use a request http in a filter the answer is simple. For exemple I have an object user with the fields : email,name,company_id.. And I have an other object company with the fields : name, createOn,... I would like use the filter like this for display the name of the user's company :

{{user.company_id | ShowNameCompany}}

So, I need to do a request http in the filter to my company controller of my backend.

I hope someone can help me.

like image 500
FlavienBert Avatar asked Nov 08 '13 16:11

FlavienBert


People also ask

What are the correct way to apply filter in AngularJS?

In AngularJS, you can also inject the $filter service within the controller and can use it with the following syntax for filter. Syntax: $filter("filter")(array, expression, compare, propertyKey) function myCtrl($scope, $filter) { $scope. finalResult = $filter("filter")( $scope.

What is the correct way to apply multiple filter in AngularJS?

Using filters in view templates Filters can be applied to the result of another filter. This is called "chaining" and uses the following syntax: {{ expression | filter1 | filter2 | ... }} E.g. the markup {{ 1234 | number:2 }} formats the number 1234 with 2 decimal points using the number filter.

What is $HTTP in AngularJS?

$http is an AngularJS service for reading data from remote servers.

How do we pass data and get data using http in angular?

get request Method Syntax: $http. get(url, { params: { params1: values1, params2:values2, params3:values3...... } });


1 Answers

I think you should not use filters that way. Filters are for transforming inputs based on optional params.

The problem here would be that you're immediately returning a promise from the filter function. And that's nothing Angular can deal with as a result from a filter.

My suggestion therefore would be this - fetch the result first, work with the filter based on the result:

var app = angular.module("my.module");

app.controller("MyCtrl", ['$http', '$scope', function(http, scope) {
  scope.hello = "foo";
  http.get('http://my.service.com').then(function(data) {
    scope.filterParams = data;
  }, function(err) {
    scope.filterParams = undefined;
  });
}]);

app.filter("filterHello", function() {
  return function(input, params) {
    if(typeof params === "undefined") {
      return "";
    }
    //work with the params here
  };
});

and in the Template:

<div ng-controller="MyCtrl">
  {{hello|filterHello:filterParams}}
</div>

Edit: Just read your explanation. To me, this would be a candidate for a directive:

app.directive("companyName", ['$http', function(http) {
  return {
    template: "<span>{{name}}</span>",
    scope: {
      companyId: "="
    },
    link: function(scope) {
      http.get("http://my.service.com/companies/" + scope.id).then(function(result) {
        scope.name = result.name;
      }, function(err) {
        scope.name = "unknown";
      });
    }
  }
}]);

and in the template:

<span company-name company-id="user.company_id"></span>

If you have a lot of companies, you should preload the names (maybe send them with the first response initially?), as you'd be bombarding your server quite a bit with requests.

like image 178
Florian Avatar answered Sep 19 '22 12:09

Florian