2

I'm trying to use AngularJS within an POST request, but I cannot use $scope within the event.

Thats my code (for demonstration purpose I just add status within the Angular construct):

myApp.controller('myController', function myController($scope) {
    $scope.myVal = [{status:"before (working)"}];

    doRequest(p1, p2, myCallback.bind(null, $scope));

    function myCallback($scope, a) {
        $scope.myVal = [{ status: a }];
    }

    function doRequest(p1, p2, callback) {
        $scope.myVal = [{ status: "prepare request (working)" }];

        var xhr = new XMLHttpRequest();
        var url = "http://...";
        xhr.open("POST", url, true);
        //....
        xhr.send(myQuery);

        $scope.myVal = [{ status: "after post send (working)" }];
        callback("after post via callback (working)");

        //callback working till this point

        xhr.onreadystatechange = function () {

            if (xhr.readyState === 4 && xhr.status === 200) {
                callback("in event (NOT working)"); 
                //This is NOT working anymore (even this point is reached)!
            }
        };
    }

as added via comments in the code, the callback is working till the EventHandler assignment.

What I'm looking for is: How to use the callback (or more precise how to make $scope available/transfered in the event handler function)?

2
  • 2
    Use $http to make the request. You are trying to modify the scope in asynchronous code that is outside of angular context. When you do that angular needs to be told to run a digest to update the view. Using $http takes care of that internally Commented Dec 2, 2017 at 19:24
  • 1
    For more information, see AngularJS $http Service API Reference. Commented Dec 2, 2017 at 20:07

1 Answer 1

3

You don't need to pass $scope into the callback, cause $scope is defined within the controller scope.

You may encounter into a problem when using "native" Ajax as you did, cause this operation is outside of Angular and angular doesn't know about, you need to make it familiar with Angular with $scope.$apply.

If you need to make a shortcut, Angular did it for you with the $http service.

You can replace the entire XMLHttpRequest with injecting $http and calling .post method:

myApp.controller('myController', function myController($scope, $http) {
    $scope.myVal = [{status:"before (working)"}];

    doRequest(p1, p2);

    function doRequest(p1, p2) {
        $scope.myVal = [{ status: "prepare request (working)" }];
        $http.post(url, myQuery).then(() => {
           $scope.myVal = [{ status: 'Finished' }]; // $scope is available here
        });
    }
}
Sign up to request clarification or add additional context in comments.

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.