2

I have to deal with an non angular library and need to create a comunication between them.

<div id="MoipWidget" data-token="{{personaltoken}}" callback-method-success="successCB" callback-method-error="errorCB"></div>

Every time that the page is loaded, I have to get a token from my server.

$http.post('https://example.org', obj)
        .success(function(data){
            $scope.personaltoken = data.token;
            //Here I call the non angular library and I get and error telling me that the token is undefined.
            //If I run the code from inside a $timeout works as I need...

        })
        .error(function(data){
             alert('error');
        });

I've also tried to run inside $scope.$apply but I get an error telling that $digest already in progress

The non angularjs library that I have to call is simple is just two lines.

var settings = {} 
LibraryCall(settings);

How can I update the model immediately?

3 Answers 3

2

I've tried to use $scope.$evalAsync as @Kjell suggested but did not work.

After reading more about $scope, I've found what I needed.

$scope.$applyAsync(function(){
    var settings = {} 
    LibraryCall(settings);
});

$scope.$applyAsync will schedule the invocation of $apply to occur at a later time.

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

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

Comments

1

I removed the error callback for brevity, don't do it in your code :)

I suppose the code you call is asynchronous, if it's not, you should not have any $scope updating problem (because all angular promises call $apply already)...

This should work:

$http.post('https://example.org', obj).success(function(data){
    $scope.personaltoken = data.token;

    otherLibrary.doSomething(data.token, function(error, result) {
        $scope.changeSomething = 'toHey';
        $scope.$apply();
    });
});

This shoud also work:

$http.post('https://example.org', obj).success(function(data){
    $scope.personaltoken = data.token;

    otherLibrary.doSomething(data.token, function(error, result) {
        $scope.$apply(function() {
            $scope.changeSomething = 'toHey';
        });
    });
})

This shoud raise the $digest already in progress error, because $http does wrap the promise callback on a $apply call already.

$http.post('https://example.org', obj).success(function(data){
    $scope.personaltoken = data.token;
    $scope.$apply(function() {
        otherLibrary.doSomething(data.token, function(error, result) {
            $scope.changeSomething = 'toHey';
        });
    });
})

2 Comments

Hello, I've just updated the post with the library code. Is very simple but I can't change their code so I have to be able to use the code: LibraryCall(settings); without passing the token directly to the library. Their library will get the token from data-token="{{personaltoken}}" is there another way to do this?
OK! I did not understand the point. Kjell Ivar did answer your question :)
0

Try using either $scope.$evalAsync() or $scope.$applyAsync(). They are made for stuff like this. It will execute the code later in time. Not that different from $timeout, but potentially faster.

$scope.$evalAsync(function(){
    var settings = {} 
    LibraryCall(settings);
})

Edit: Just to quote Ben Nadel on the difference between $timeout and $evalAsync, from this post:

So, in essence, $scope.$evalAsync() combines the best of both worlds: When it can (which is most of the time), it will evaluate your expression in the same tick; otherwise, it will evaluate your expression in a later tick, which is exactly what $timeout() is doing.

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.