0

When page is loading first time, I'm getting my thingsList filled. But then I need choose option with ng-click, it triggers function doSomething() which is getting new thingsList. I can see at debug mode that there is a new list, but there's no binding and datatables still showing me the old thingsList.

I'd really like to solve this without dtOptions is it's possible.

I'm using pretty simple "angular way" with datatables:

<tr ng-repeat="thing in thingsList">
   <td>{{thing.id}}</td>
   <td>{{thing.name}}</td>
</tr>

and my controller looks like:

.controller('ThingsController', ['$http', '$scope', function ($http, $scope) {

    this.getThing = function () {
        $http.get(....).then(
            function success(response) {
                $scope.thingsList = response.data;
            },
            function error(data) {
                console.log(data);
            }
        );
    };

    this.getThings();


    this.doSomething = function (id) {
        $http.get(....).then(
            function success(response) {
                $scope.thingsList = response.data;
            },
            function error(data) {
                console.log(data);
            }
        );
    };

}]);
1
  • 1
    can you provide plunkr Commented Jul 5, 2016 at 16:27

2 Answers 2

2

Try using

$scope.thingsList.splice(0);   // clears the array without losing reference
Array.prototype.push.apply($scope.thingsList, response.data); // inserts new data to existing array

instead of $scope.thingsList = response.data; in doSomething function.

Sign up to request clarification or add additional context in comments.

4 Comments

well, as I said I get a new thingsList array when ng-click triggers the function. But it's not binding to the datatable. But thanks anyway.
I thought your problem might be actually connected with replacing $scope.thingsList with a new array. Although you can see new data in debugger, it doesn't mean that view knows about the change. It might still be referenced to the old array. My solution ensures that reference to the array doesn't change - only the data inside it is updated.
ok, used your solution and put getThings to ng-init. Now it works
Personally, I don't like the use of ng-init in this way. Also, Angular documentation advices against it as someone mentioned in comments in the link provided by Vishal Rao. I find a private initialize function declared and executed at the bottom of the controller more readable. But it's a matter of taste I guess :-) I'm glad I could help a bit.
1

So I'm guessing the reason its happening is because the getThings() function is being called every time the controller is used. You might want to modify your controller code in this way and try:

.controller('ThingsController', ['$http', '$scope', function ($http, $scope) {

$scope.getThing = function () {
    $http.get(....).then(
        function success(response) {
            $scope.thingsList = response.data;
        },
        function error(data) {
            console.log(data);
        }
    );
};


$scope.doSomething = function (id) {
    $http.get(....).then(
        function success(response) {
            $scope.thingsList = response.data;
        },
        function error(data) {
            console.log(data);
        }
    );
};

}]);

Now this will solve your problem of the list not updating when you choose your option with ng-click but your list won't get loaded by default when you load the page since getThings() isn't being called.

My suggestion for that would be to use use ng-init as described in the answer to this question: How to execute angular controller function on page load?

or better yet use $scope.on in this manner in your code:

.controller('ThingsController', ['$http', '$scope', function ($http, $scope) {

$scope.getThing = function () {
    $http.get(....).then(
        function success(response) {
            $scope.thingsList = response.data;
        },
        function error(data) {
            console.log(data);
        }
    );
};

$scope.$on('$viewContentLoaded', function() {
   $scope.getThing();
})

$scope.doSomething = function (id) {
    $http.get(....).then(
        function success(response) {
            $scope.thingsList = response.data;
        },
        function error(data) {
            console.log(data);
        }
    );
};

}]);

In case you're using routing you can change the '$viewContentLoaded' to '$routeChangeSuccess' for ng-route or '$stateChangeSuccess' if you're using ui-router. (Don't worry about this unless you're using routes to change views)

2 Comments

there's a lot of things. But put getThings to ng-init really helped, thanks. One thing I don't understand, in debug mode (F12) I don't see any calls of getThings after init of Controller anyway. What did it change actually?
One easy way to find out if it was actually calling it multiple times is just placing a console.log() inside the function so you can see how many times it was called. I suggest you try that and see if the statement inside the log is printed every time you trigger the ng-click.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.