FlavienBert FlavienBert - 1 year ago 74
AngularJS Question

Angular : How use $http in a filter

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">

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.

Answer Source

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">

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download