Search code examples
javascriptangularjsjsphttpangularjs-scope

How to update scope variable value in view after http call?


I am making my first project using Angularjs 1.4.3.

In my controller I am making a http request, in the success method of this http request I am updating a scope variable. In http call I am getting the latest values but in the view side its not updating the values.

Plunker Link (@rupesh_padhye thanks). (Since it is calling the servlet action, so no data will be shown in Plunker)

app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {



    $scope.groups = []
        $scope.loadAllMeasure = function() {
            $http.get("fetchAllMeasure")
            .success(function(data) {
                console.log("Before insert");
                console.log($scope.groups);

                $scope.groups = data.measures;

                console.log("After insert");
                console.log($scope.groups);
            })
            .error(function() {
            });
        };

        $scope.loadAllMeasure();

$scope.submit = function (form) {
$http({
        method: 'POST',
        url: 'saveMeasure',
        data: {
               id: form.id,
               name: form.name,
               description: form.description
              },
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        }).success(function(data, status, headers, config) {
           $scope.loadAllMeasure();
        }).error(function(data, status, headers, config) {
   });
 }

})

And whenever I am performing any CRUD operation on measures I am calling a method $scope.loadAllMeasure();. But its not updating the values in the view (jsp) page.

I have tried $scope.$apply method but I am getting Error: $digest already in progress.

When I printed the value for $scope.groups using console.log inside success method, then its showing the latest values.

In my view (jsp) page I am just using ng-repeat function to show all the records in table format.

Code for my view page (minimal code) -

<div ng-repeat="group in groups | orderBy:'name'">
    <div>
        <input type="checkbox" id="checkbox-{{group.id}}" class="ui-checkbox" /><label for="checkbox-{{group.id}}">{{group.name}}</label>
    </div>
    <div>{{ group.description}}</div>
    <div>   
            <div class="fa fa-pencil button" data="{{group.id}}" id="{{::elementId}}" ng-click="showEditForm(group.id, $event)"></div>
            <div class="fa fa-trash button" data="{{group.id}}" ng-click="deleteGroup(group.id)"></div>
            <div class="fa fa-clone button" data="{{group.id}}" id="{{::elementId}}" ng-click="showCloneForm(group.id, $event)"></div>
    </div>
</div>

Values in console.log are

Before insert
Object { id=1,  description="Measure Description1",  name="Demo"}]

And

After Insert
 [Object { id=1,  description="Measure Description1",  name="Demo"}, Object { id=2,  description="Description2",  name="Demo2"}]

How to update scope variable value in view after http call?


Solution

  • I cant see anything wrong with your example code.

    I have created a JSFiddle to try and help you.

    The server call has been replaced by a setTimeout function that returns a promise.

    Please see JSFiddle https://jsfiddle.net/sjwkbzxa/

    Please see example below:

    <div data-ng-controller="TestController as vm">
        <button data-ng-click="loadAllMeasure()">Load List from Server</button>
        <ul>
            <li data-ng-repeat="group in groups | orderBy:'name'">
                <span>{{group.description}}</span>
            </li>
        </ul>
    </div>
    

    The javascript:

    angular.module('application',[]).controller("TestController", ['$scope', '$q', function($scope, $q){    
        $scope.groups = [{ id:1,  description:"Initial List",  name:"Demo"}];
    
        $scope.loadAllMeasure = function(){
           loadData().then(function(data){
             $scope.groups = data;
           });
         };
    
        function loadData(){
            var deferred = $q.defer();
            setTimeout(function(){
                var data = [{ id:1,  description:"Measure Description1",  name:"Demo"}, { id:2,  description:"Description2",  name:"Demo2"}];
                deferred.resolve(data);
            }, 3000);
           return deferred.promise;
        }
    }]);
    

    Maybe you are missing something on your side that we cant see?