2

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?

19
  • 2
    You don't need to update scope variable, $http does it automatically Commented Dec 1, 2015 at 9:53
  • Then why its showing old values in view? Commented Dec 1, 2015 at 9:54
  • Can you post the view? Commented Dec 1, 2015 at 9:56
  • You need to use ng-model="id", not data="{{group.id}}" Commented Dec 1, 2015 at 10:03
  • data="{{group.id}}" works with no issue, and I am not showing id to user. Commented Dec 1, 2015 at 10:13

5 Answers 5

8

After assigning the new data to a $scope variable call:

$scope.$digest();

This will update the current scopes values

reference here: https://docs.angularjs.org/api/ng/type/$rootScope.Scope

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

1 Comment

Thank you, it works for me. I was updating a $scope variable into a event handler function (.on( ) of socket.io) but the variable value just changed in the view when the function was called for the second time.
2

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?

11 Comments

Thanks, I am actually not able to demonstrate it in fiddle, since my data is coming from database through servlet response. With static data as you mentioned is working fine, but with dynamic data its not working. I can see the updated values in database, console.log but not in View :(
@Deepu If it does not work with data from the server it means the data you are getting from the server is not in the correct format. If you use a setTimeout or use data from a API makes no different.
Data is in correct format, if I refresh the page then I am getting all updated data. Because when controller loads I am calling $scope.loadAllMeasure method, but even after the save measure I have called the same method, then it doesnt update the list. But when I refresh the page it displays all data.
Can you add the code you mention in "Because when controller loads I am calling $scope.loadAllMeasure method"
Yes its immediately after declaration of $scope.loadAllMeasure, updated in question.
|
1

I'm a little late to answer this, but here are my 2 cents:

A simple assignment of the server data (response.data) to a $scope object didnt seem to work for me

$scope.something = response.data //didn't work

So, I returned a promise object from the service into the controller and then use

angular.copy(response.data,$scope.something) 

to copy the values returned from the server. You could also pass the $scope.something to the service as a parameter to the function and have angular.copy in the service function as well, but i don't know if it's a good practise to do that.

2 Comments

$http is async call, if you get delay in response then in angular.copy will have different value than the response value. Anyways thanks for your response.
Sorry for not being clear... I use angular.copy(source,dest) in the 'then' clause of the promise returned by the $http call. So far thankfully I've not seen the problem you've reported, but will keep an eye. Thanks for the heads up.
0
 $scope.loadAllMeasure = function() {
     CalltoServer();
 };

 CalltoServer = function() {
    return $http.get("fetchAllMeasure")
    .success(function(data) {
        $scope.groups = data.measures;
    })
    .error(function() {
    });
 }

try this , the success will be after 2 or 3 seconds so i guess inside the event it takes rist to bind

5 Comments

No luck with this one also :(
ng-controller="measuresCtrl" added ? or controller declared in routing ? if not it wont work for some scenario , i didnt find any error on your code
My controller is measuresCtrl and fetchAllMeasure is action method from servlet.
Whats the difference by adding extra method?
.success(function(data) { //Here it will come after the success }) the $http request is in another angular event , that makes it to difficulties in binding
0

Hey I also faced the same issue and if anyone is still looking, it is caused by change in the $scope variable inside the $http. I think a new $scope is being created inside the success function(some prototypical inheritance stuff). So make a copy of the variable $scope, something like

var s = $scope;

and then change

s.groups = someData;

Your code:

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


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

            s.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) {
});
}
})

Comments

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.