AjRev
AjRev

Reputation: 95

Angularjs $scope is not updated

I am developing an angular-ionic-firebase application. I am struggling on an issue where I am unable to update a $scope in my html. My must resolve {{uevent}} and update the html with the result of {{uevent}}. My html code is below.

**<ion-view view-title="{{uevent}}">**
<ion-tabs class="tabs-stable tabs-icon-top">
    <ion-tab title="Buddies" icon="ion-ios-people" ng-   click="showBuddies(a)">
    </ion-tab>
    <ion-tab title="Summary" icon="ion-navicon" ng-click="billSummary()">
    </ion-tab>
</ion-tabs>

my angular code is below. CurrUser is a factory. I've defined an empty $scope.uevent which I am expecting to update using a value returned from a factory.

var eventid = CurrUser.getEventid();
$scope.uevent = " ";

function updateEvent(desc) {
$scope.uevent = desc;
console.log($scope.uevent);// I am able to see the value returned from the factory. This function is executed below in the for loop.
};

// promise that returns a value from the factory - CurrUser.
CurrUser.getEventdesc(eventid).then(function (result) {
var description = result;
var desc;
for (var itemID in description) {
var tmp = description[itemID];
desc = tmp.Description; // This contains the value that must be updated to $scope.uevent
updateEvent(desc); // Calls the function defined above to update $scope.uevent.
};
});

I've been on this since last night without any clues. Any help is greatly appreciated and as always, thanks for your time.

UPDATE #1:(07 July) When i added a timeout of 1 sec, the view was updated to the correct value.

function updateEvent(desc) {
$timeout(function(){
    $scope.$apply(function () { 
        $scope.uevent = desc;
        })
    },1000);
    };

Regards,

Upvotes: 0

Views: 1602

Answers (3)

Suren Srapyan
Suren Srapyan

Reputation: 68655

There are 2 execution context when You work with AngularJS - Angular Context and JavaScript Context.
When you are changing the data in AngularJS Context, the digest loop begins and all data updates, but when you change data in the JavaScript Context (e.g setTimeout, setInterval and so on), Angular doesn't know about the changes so it doesn't update the data. In JavaScript Context you must change your data in scope.$apply() method to run the digest loop manually. So your code will look like

        var eventid = CurrUser.getEventid();
        $scope.uevent = " ";

        function updateEvent(desc) {
        $scope.$apply(function(){
           $scope.uevent = desc;
        });

        console.log($scope.uevent);// I am able to see the value returned from the factory. This function is executed below in the for loop.
        };

        // promise that returns a value from the factory - CurrUser.
        CurrUser.getEventdesc(eventid).then(function (result) {
        var description = result;
        var desc;
        for (var itemID in description) {
        var tmp = description[itemID];
        scope.$apply(function(){
    desc = tmp.Description; // This contains the value that must be updated to $scope.uevent
       })

        updateEvent(desc); // Calls the function defined above to update $scope.uevent.
        };
        });

For more.If there is an Angular JS alternative, you must use it,because it runs te digest loop automatically($timeout instead of setTimeout(), $interval instead of setInterval())

Upvotes: 2

Srijith
Srijith

Reputation: 1444

Where is your controller defined in the html? Or is it in your app.js. Anyways, for a start can you do a $scope.$apply in your updateEvent function?

function updateEvent(desc) {
   $scope.$apply(function(){
     $scope.uevent = desc;
   });
  console.log($scope.uevent);
};

I dont know what happens in your getEventDesc() method but if there is a non-angular ajax request or something, then it might need the $apply to trigger the digest cycle and update watchers.

Detailed explanation below.

Reference: This awesome informative post -> https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply()

AngularJS provides wrappers for common native JS async behaviors:

Events => ng-click Timeouts => $timeout jQuery.ajax() => $http This is just a traditional async function with a $scope.$apply() called at the end, to tell AngularJS that an asynchronous event just occurred.

$scope.$apply() should occur as close to the async event binding as possible.

Do NOT randomly sprinkle it throughout your code. If you are doing if (!$scope.$$phase) $scope.$apply() it's because you are not high enough in the call stack.

Whenever possible, use AngularJS services instead of native. If you're creating an AngularJS service (such as for sockets) it should have a $scope.$apply() anywhere it fires a callback.

Upvotes: 1

Ved
Ved

Reputation: 12093

Try this; $apply is used to trigger $digest .

function updateEvent(desc) {
  $timeout(function(){
   $scope.uevent = desc;
   $scope.$apply();
},0)
};

Upvotes: 1

Related Questions