0

I'm just curious why the following code is working:

<script>
    var app = angular.module('VEL',[]);
    app.controller('VELControl', function($scope, $http) {
        $.getJSON("../json/dict.php?p="+$_GET['p'], function(response){
        $scope.velData = response;
    });
    alert($scope.velData); // also works with alert($scope);
  });

But when I remove the alert(...) it stops working.

Could anyone explain me why or refer to a documentation?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
maragnar9
  • 1
  • 1
  • what do you mean by "stops working"? what stops working? – Ken Bellows Mar 31 '16 at 12:12
  • 1
    Also, you should definitely be using the `$http` service instead of jQuery's ajax methods, since `$http` is tied into Angular's digest cycle – Ken Bellows Mar 31 '16 at 12:13
  • The data will not be displayed but will still received. – maragnar9 Mar 31 '16 at 12:15
  • By stops working, do you mean that it won't print anything? The alert simply creates the alert box, if it is removed, the $scope.velData is still set, but there's no way to see it if you don't do anything else with it – philoniare Mar 31 '16 at 12:15
  • Please read this answer to understand async callbacks http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call/16825593#16825593 – Daniel Krom Mar 31 '16 at 12:16
  • The reason you don't see anything (assuming you mean that you have something like `{{velDelta}}` in your view) is most likely because Angular doesn't know that the ajax call completed or that the scope was updated, so it doesn't realize that it should update the view. Swap `$.getJSON()` out for `$http.get(url).then(function(response){...})` and it should work like you expect – Ken Bellows Mar 31 '16 at 12:17
  • @DanielKrom OP's problem isn't that they don't understand Async; he's handling the result in a callback function, which is the right thing to do. What's missing is an understanding of Angular's digest cycle. – Ken Bellows Mar 31 '16 at 12:19
  • @Satpal I don't think this is a duplicate of the async question; the problem deals with Angular's digest cycle, not getting the result back from an async function – Ken Bellows Mar 31 '16 at 12:20
  • @KenB He's doing the alert after the callback.... `$scope.velData = response;` is the only code inside the callback – Daniel Krom Mar 31 '16 at 12:26
  • I know what async is but couldn't explain why a alert affect the script. Using the $http.get() I get only 5 of 32 entries and all of these entries are empty. – maragnar9 Mar 31 '16 at 12:28
  • @DanielKrom right, but that's not really the question he's asking (from what I can tell); I think what he wants to know is why the view doesn't update after the ajax call completes, even though his alert (which, IIRC, is asynchronous by nature,a nd thus works by accident) does work – Ken Bellows Mar 31 '16 at 12:28
  • @maragnar9 you're saying that the *result of the ajax request* actually changes when you use `$http` instead of jQuery? that doesn't make much sense, and I'd suspect a server-side issue... – Ken Bellows Mar 31 '16 at 12:30
  • maybe try a `console.log(arguments)` from the success callback to make sure you're really getting back what you think you are? – Ken Bellows Mar 31 '16 at 12:31
  • Despite the servers send the data with a delay of 400ms it is well formated in JSON. – maragnar9 Mar 31 '16 at 12:35
  • @KenB in $http.get after assignmend of $scope.velData = response: Object { data: Array[32], status: 200, headers: headersGetter/<(), config: Object, statusText: "OK" } angular.php:179:4 – maragnar9 Mar 31 '16 at 12:36
  • 1
    By using $http.get i have forgotten to assign with response.data instead of response. Now i have all entries displayed in a propper way – maragnar9 Mar 31 '16 at 12:46
  • I'll post as an answer then, if you don't mind marking as correct :) – Ken Bellows Mar 31 '16 at 12:49

1 Answers1

0

The main problem is that you're using jQuery's $.getJSON() method, which Angular doesn't know anything about. Angular is great at tracking when asynchronous events occur and updating the view when they complete, but you have to use Angular's services to take advantage of this.

Angular gives us the $http service for making AJAX calls. Since $http is tied into Angular's digest cycle (read up on this if you've never heard of it, it's critical to understanding how Angular works), Angular will update the view after $http returns data and its callbacks are run.

Rewrite your controller like this and it should work:

app.controller('VELControl', function($scope, $http) {
    $http.get("../json/dict.php?p="+$_GET['p']).then(function(response){
      $scope.velData = response.data;
    });
});

As an aside, your alert() working with the old method was probably a fluke based on how fast your server returned the data. As I understand it, alert() runs asynchronously anyway, so when you called alert($scope.velData), this was probably pushed onto the end of the browser's execution queue, and before it was reached the AJAX call returned and set the value you needed. If your server had been slower, you probably would have alerted undefined and then received your data. If you have control over the server (which it looks like you do), this would probably be a fun experiment to try: put in a sleep(10) or some similar wait to force the server to take a long time; try different values and see what happens with that alert() statement.

Ken Bellows
  • 6,711
  • 13
  • 50
  • 78