nbi
nbi

Reputation: 1386

angularjs not updaing propeties when promises used

I am using service to get JSON object using promises. It is then converted into array and assign to a property which is in $scope object. The problem is that array is not getting updated or any properties inside promise then() method.

Controller

var searchController = function ($scope, $SPJSOMService) {
    $scope.myName = "old name";
    $scope.getUsers = function ($event) { //called on button click
        $event.preventDefault();
        var queryText = "test user";
        $SPJSOMService.getUsers(queryText)
        .then(function myfunction(users) {
            $scope.userCollection = JSON.parse(JSON.stringify(users)).d.results;
         //   $scope.$apply();  this line throwing error. $rootScope in progress
            $scope.myName = "new name"; //not getting updated
        }, function (reason) {
            alert(reason);
        });
    };
};

Service

var SPJSOMService = function ($q, $http, $rootScope) {
    this.getUsers = function (userToSerach) {
        var deferred = $q.defer();

        $http({
            url:'some url',           
            method: "GET",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-Type": "application/json;odata=verbose"
            }
        })         
         .success(function (data, status, headers, config) {
             deferred.resolve(data); //successfully return data
         })
    .error(function (data, status, headers, config) {
        deferred.reject(data);
    });
        return deferred.promise;
    };
};

Updated

index.html

<div ng-include="'Search.html'">
</div>
<div ng-include="'searchResults.html'"></div>

search.html

<div id="containerDiv"  ng-controller="searchController as search">
   <input class="button" type="button" ng-click="getUsers($event);" value="Search" id="btnSearch" /> 
</div>

searchResults.html

<div ng-controller="searchResultController as result">
<table >
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>EMail</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr ng-repeat="item in userCollection">
                            <td>{{$index}} {{item.userName}}</td>
                            <td>{{$index}} {{item.userEmail}}</td>
                        </tr>
                    </tbody>
                </table>
            </div>

So search.html returns the data by calling the service and I am trying to pass it to the page namely searchResults.html which have its own controller.

   $scope.users = $scope.userCollection;

Service class correctly returning data, but the problem is inside then(), which is not updating $scope.userCollection, hence UI is not getting updated.

Please help me out, what am I missing here.

Upvotes: 1

Views: 75

Answers (2)

Alex Pollan
Alex Pollan

Reputation: 873

In angular controllers can bind to the view in two ways:

  • "controller as"
  • through scope

It looks you are using the "controller as" flavor here...

<div ng-controller="searchResultController as result">

Refer to https://docs.angularjs.org/api/ng/directive/ngController for more information.

Change your controller code to:

var searchController = function ($scope, $SPJSOMService) {
    //note use of "this" instead of "$Scope"
    var _this = this;

    _this.myName = "old name";
    _this.getUsers = function ($event) { //called on button click
        $event.preventDefault();
        var queryText = "test user";
        $SPJSOMService.getUsers(queryText)
        .then(function myfunction(users) {
            _this.userCollection = users.d.results; //You don't need JSON.parse not JSON.stringify 
            _this.myName = "new name"; 
        }, function (reason) {
            alert(reason);
        });
    };
};

and in your view use the controller "alias":

<div ng-controller="searchResultController as result">
   ...
   <tr ng-repeat="item in result.userCollection">
... 

Upvotes: 2

Tekill
Tekill

Reputation: 1201

You have to push it to the new array I think. Have you tried this in your then statement?

$scope.myName.push("new name");

It should put it in the existing array. Let me know if it works.

Upvotes: 0

Related Questions