Levi Cole Levi Cole - 4 months ago 30
jQuery Question

AngularJS scope variables not updating in jQuery promise/deferred

I am building a single page application on

AngularJS
and I have a
controller
set up with a function that is run on a button click. This function runs with a promise. When the function is resolved I am updating a root variable and changing the
$location
path. But the root variable and
$location
dont seem to be updating.


Please note this all code is exampled from production


DOM:

<div ng-controller="ExampleController">
<button ng-click="button_function('I am a variable')">Run function</button>
</div>


Controller:

app.controller('ExampleController', ['$scope', '$location', function($scope, $location) {

$scope.button_function = function(variable) {
$scope.$root.show_something = true;

my_function.something(variable).done(function(data) {
if (data) {
$scope.$root.show_something = false;
$location.path('/go-to-path');
} else {
alert('Something went wrong');
}
}]);
};

}]);


This is the
my_function
code:

var my_function = {
something: function(variable) {
var deferred = $.Deferred();

var window = window.open('http://dynamic.url/', '_blank');

$(window).on('loadstart', function(e) {
var url = e.originalEvent.url;

if (url === 'http://dynamic.url/expected_response') {
window.close();
deferred.resolve({
key_1: 'data',
key_2: 'more data'
});
}

});

return deferred.promise();
}
};


All looks good right? But when the
my_function.something(variable)
is "done" the
$location
and
$scope.$root.show_something
don't seem to update.

Am I doing something wrong?

Thanks

Answer

I have found the fix.

In my controller after the deferred is "done" I wrapped my variables in $timeout

app.controller('ExampleController', ['$scope', '$location', '$timeout', function($scope, $location, $timeout) {

    $scope.button_function = function(variable) {
        $scope.$root.show_something = true;

        my_function.something(variable).done(function(data) {
            if (data) {
                $timeout(function() {
                    $scope.$root.show_something = false;
                    $location.path('/go-to-path');
                }, 1);
            } else {
                alert('Something went wrong');
            }
        }]);
    };

}]);

Answer found here

Comments