Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS use a function in a controller to return data from a service to be used in ng-repeat

I am trying to use a function in a controller to return data so that I can re-use the function across the app to call the data as well as refresh it occasionally.

My code appears correct, but in practice, crashes the browser on each load.

I am able to get it to work by using an E directive and then placing the element in the partial, but that doesn't accomplish what I need.

Ultimately, I would like to do something like this:

<div ng-repeat="user in getListUsers()">{{ user.somedata }}</div>

I have tried various things to get it to work in testing, including putting the $http in the controller, all with the same results.

If I assign a variable in the controller method instead of returning the data, that works, but then I would need to call the method in the controller and I don't want it to run by default. Just looking to make the call in the templates when needed.

Any help in figuring out why this is not working would be great. Thanks.

Here is what I have that is not functioning...

elite.controller('UserController', function($scope, User){

    $scope.getListUsers = function(){
        User.listUsers().then(function(response){
            return response.users;
        });
    }

});

elite.factory('User', function($http){
   var User = {
      getUser: function(id){
          return $http.get('/user/' + id + '/settings').then(function(response){
              return response.data; 
          });
      },
      listUsers: function(){
        return $http.get('/user/').then(function(response){
          return response.data;
        });
      }
   }
   return User;
});

Edit:

Using some of the ideas below, I am able to get the functionality I wanted, just in a different way. Basically, I want the data to load on demand, rather that up front, as I am trying to group all User logic in that controller and I don't want the full data to load for every user. I am using $rootScope temporarily until I figure out some scoping inheritance issues, as using $scope.users ends up with a null value in the template. I can see the AJAX call coming back, but not sure where it's going, but that's another issue.

elite.controller('UserController', function($scope, $rootScope, User){

    $scope.getListUsers = function(){

        User.listUsers().then(function(response){
            $rootScope.users = response.users;
        });
    };

});

And in a nav element I have this:

<div ng-controller="UserController">
<a ng-href="/#user/list" ng-click="getListUsers()">user list</a>
</div>
like image 361
Jazzy Avatar asked Jan 06 '14 04:01

Jazzy


People also ask

How pass data from controller controller to AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.

What is Ng-repeat in AngularJS?

AngularJS ng-repeat Directive The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.

What is the use of NG-controller in AngularJS?

The ng-controller Directive in AngularJS is used to add a controller to the application. It can be used to add methods, functions, and variables that can be called on some event like click, etc to perform certain actions.

Can we call function from another controller in AngularJS?

In AngularJS when it comes to communicating between controllers, one would naturally assume to reference another controller you can simply inject it into another controller and call its methods: however, you cannot do that.


1 Answers

This is about $digest, $watch and ng-repeat. You can find a lot of answers by simply googling it or check out link given by Jsplaine.

In short, your getListUsers() function returns a list of Users every time it is called. However, every returned list is a new collection ( array ). To angular, this means it has to update the display of the list on the page. After each update, Angular actually check a few times to see if the list becomes stable or not by calling getListUsers() function again. Every time angular found that the list is different, so it keep updating the list and keep calling the getListUser function.

To solve this problem, you can create a variable holding the user list:

 $scope.userList = [];

and also the function to update the list

$scope.reloadListUsers = function(){
    User.listUsers().then(function(response){
        $scope.userList = response.users;
    });
}

Then in the ng-repeat directive

<div ng-repeat="user in userList">{{ user.somedata }}</div>

Where you want to reload the list, simple call the reloadListUsers function .

<button ng-click="reloadListUsers()" > reload </button>

The reason behind is that now the variable userList is used in the binding instead of the function call expression, and it becomes stable once the list is loaded.

like image 108
David Lin Avatar answered Oct 21 '22 13:10

David Lin