AngularJS custom filter unknown provider error

thousight picture thousight · Aug 13, 2015 · Viewed 8.8k times · Source

I created this filter to transform userID to user's name:

angular.module('idToName', ['userService'])

.filter('idToName', function(User) {
  User.allUsers()
  .success(function(data) {
    userData = data;
  });
  var assignee;
  return function(IDs) {
    for (var j = 0; j < userData.length; i++) {
      for (var i = 0; i < IDs.length; j++){
        if (IDs[i] == userData[j]._id) {
          assignee[i] = userData[j].firstname + ' ' + userData[j].lastname + ' ' + userData[j].cname;
        }
      }
    }
    return assignee;
  }
})

It takes in an array of userIDs, and it should find the corresponding userData object and return its names.

But when I run it, it gets this error:

Error: $injector:unpr
Unknown Provider

Unknown provider: idToNameFilterProvider

So what did I do wrong? I would appreciate any help.

Answer

Joy picture Joy · Aug 13, 2015

Please check working demo: JSFiddle

angular.module('idToName', [])
    .factory('userService', ['$http', function ($http) {
    var users = [];
    return {
        all: function () {
            return $http.get('http://jsonplaceholder.typicode.com/users');
        }
    };
}])
    .filter('idToName', function () {
    var assignee = [];
    return function (userData, IDs) {
        if (!userData || userData.length === 0) {
            return 'loading...';
        }
        for (var i = 0; i < userData.length; i++) {
            for (var j = 0; j < IDs.length; j++) {
                if (IDs[j] == userData[i].id) {
                    assignee[i] = userData[i].name + ' ' + userData[i].username + ' ';
                }
            }
        }
        return assignee;
    }
})
    .controller('MyCtrl', ['$scope', 'userService', function ($scope, userService) {
    $scope.IDs = [1, 2, 3, 4];
    $scope.users = [];
    userService.all().success(function (data) {
        $scope.users = data;
    });
}]);

Use it in HTML:

<div ng-app="idToName" ng-controller='MyCtrl'>{{ users | idToName:IDs }}</div>

Some issues in your code:

  1. Your userData is obtained asyncly, when you call the filter, the userData may not have arrived yet. And your filter should not be fetching data. Because it is not its job. You'd better separate the data-fetching logic to some independent logic. So I created another service userService

  2. You nested for loop is messed with the i and j variables. I have made them working.

  3. idToName is not a good module name.


Update 1

Learned from comments of @tuckerjt07 and @ach, please check your JavaScript inclusion and module dependency code. There must be something wrong when trying to inject the filter. Seems the filter itself is not found within the context.