-1


I want to create a dynamic page (that's why i'm using angular.js) according to datas from my localhost database. I'm connecting into my DB using a jQuery ajax call function :

var ajaxCall = function(request,datas,async,onSuccess){
    $.ajax({
        async: async,
        url: 'data.php',
        type: "POST",
        data: {
            request: request,
            datas: datas
        },
        dataType:"json",
        success:function(returns){
            if(onSuccess != null)
                onSuccess(returns);
        }
    });
};


This is my angular file, including the ajaxCall to get my values :

(function(){
    var app = angular.module('user', [ ]);

    app.controller('MemberController', function() {
         var user= this;
         user.members= [];

         ajaxCall("getMember",null,false,function(result){
             for(var number in result)
                 user.members.push(result[number]);
         });

         setTimeout(function(){
             console.log(user.members)
         }, 2500);
     });
})();


From the ajax call, I receive a JSON (valid on JSONLint) but in my angular code, when I console.log(user.members) (even with a TimeOut of several seconds), the value of the array is still [] and I can't use it on my html page.

Do you have any idea why ? Or how can I change my code to make it work ? Thank you !

tektiv
  • 14,010
  • 5
  • 61
  • 70
  • can you post the angular controller too – sanjeev May 06 '15 at 11:44
  • Please put your `console.log` right before the closing `});` of your example code. This would be the only correct place to check user.members – devnull69 May 06 '15 at 11:44
  • 3
    People, stop mixing jQuery and Angular. Stop using jQuery's ajax instead of Angular's $http service. _Unload_ jQuery and find a 100% Angular way of doing things. – Jeremy Thille May 06 '15 at 11:51
  • After following most of angular tutorial on codeschool, I wanted to .. But I didn't know how to call my localhost database with a $http injection. I also had an already-made function on jQuery, that's why I wanted to try with both together. Have you got a link (tutorial, video, SO topic ...) to show me how I can access localhost databases ? @sanjeev Edited :) – tektiv May 06 '15 at 11:57
  • `$http` syntax is the same as `ajax`. `$http.get("someUrl", { "some":"data"}).success(function(data){ /* do something with data */}).error(function(err){ console.log(err) })` . The only difference is, it works directly in Angular without any dirty workaround. – Jeremy Thille May 06 '15 at 12:17
  • You should not do 'for in'. Instead do 'for of' if es6 is supported, or a regular 'for (var i...' – Artūras May 06 '15 at 12:18

3 Answers3

1

enter link description hereInside your AJAX callback you need to tell Angular that you have changed it's model, outside Angular world.

ajaxCall("getMember",null,false,function(result){
             for(var number in result)
                 user.members.push(result[number]);
             $scope.$apply(); // this will tel Angular to loop for changes in $scope
         });

But I would encourage you to replace it with $http call:

app.controller('MemberController', function($http) {

         $scope.members = [];

         $http.post("data.php" ,{ request: request, datas: datas })
        .success(function(result){
             console.debug(result);
             for(var i=0; i<result.length; i++)
                 $scope.members.push( result[i] );
         });
     });

With this code you don't need to call $apply, because $http is Angular service, and $apply will be called automaticaly at the end of success predicate.

More about $http.get with arguments you can find here. $http with post is inside this answer.

Update:

You should assign members to controller $scope, that way your results will be visible on the view (I've updated my code).

Secondly you said, that your action on server side is a read operation, in this case replace your POST with GET, like so:

 $http.get("data.php" ,{params: { request: request, datas: datas } })

Remember:

  1. POST - when you remove, add, update model
  2. GET - when you read objects

Good luck:)

Community
  • 1
  • 1
Beri
  • 11,470
  • 4
  • 35
  • 57
  • 1
    Secondly, when working with AJAX, don't trust timeout to check it's results, you need to change your logic, and use fetched data inside succes predicate, rather than wait x seconds. – Beri May 06 '15 at 11:58
  • That helped me a lot .. But one more thing : I edited my post to show you my ajaxCall function, and I don't know how make the $http injection look like it (wih $_REQUEST values and things like that), do you have any idea ? – tektiv May 06 '15 at 12:07
  • @tektiv I've updated the answer, see if it helps. As you can see, Angular is shorter, and code is still readable:) – Beri May 06 '15 at 12:13
  • I like your new way, I could do a new function with it .. But it doesn't work : it lets me know that there are 2 items on database, but doesn't send anything. Any idea why ? ("Response" in FireBug shows up, but shows nothing) – tektiv May 06 '15 at 12:18
  • What response code do you receive? Can you debug into it on server side? In my example you are calling POST method, so I assume this will persist something. For fetching data, use get. – Beri May 06 '15 at 12:22
  • I don't send any data when I do the $http call, I don't need it, my $sql is a SELECT. I'm sending a request var because I have a switch in my data.php with every case of request (including "getMember" which echo the result of a JSON created in PHP with what I have from the SELECT query). But fnally, I don't receive anything : my user.members is still [] after the $http call – tektiv May 06 '15 at 12:30
  • Perfect, that works very well ! Thank you again, and sorry about bothering you ! – tektiv May 06 '15 at 12:41
1

var app = angular.module('app', []);

app.controller('yourController', ['$scope', '$http',
  function($scope, $http) {
    $scope.user = {
      data: []
    };
    $http.get('http://echo.jsontest.com/one/1/two/2/three/3').success(function(results) {
      console.log(results);
      for (var number in results)
        $scope.user.data.push(results[number]);
    });
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<html ng-app="app">

<body ng-controller="yourController">

  {{user.data}}

</body>

</html>
Kostas
  • 1,903
  • 1
  • 16
  • 22
0

This is not my favorite way to do it but in your case call:

$scope.$apply();

After you've updated your collection.

I think what's happening is that Angular needs to run a digest cycle to update views and right now you haven't told it to do that because you're running a straight ajax call. If your call was initiated by an "ng-"event angular would then know that stuff is going on and wait for calls to finish...before updating the views for itself.

So try the $scope.$apply(); at first and if you can call your update function via an ng-click or something try that without the $scope.$apply(); and see if that works as well.

Then you should look into using $http to make REST calls I personally like the ng-resource add-on module...

Thierry Blais
  • 2,848
  • 22
  • 41
  • See my comment above. That's what happens when you mix jQuery and Angular. jQuery is outside Angular's "world", it's clumsy, and you need dirty tricks like `$scope.$apply()` to tinker and make things work. Definitely not the way to go. The answer is correct, note. – Jeremy Thille May 06 '15 at 11:54
  • Maybe true, but this is all part of the learning process, and I didn't want to offer up a solution of: It's all crap, re-write everything...so try to find a solution for the jQuery ajax call, that way we can all learn how things work, and then make a judgement about what technology to use in another instance. – Thierry Blais May 06 '15 at 12:01
  • I agree, I said your solution works. But since the OP is learning (as we all do), my best advice is : STOP that, remove jQuery and find an Angular way of doing things. Tring to mix both won't do any good and that's not a good way to learn. – Jeremy Thille May 06 '15 at 12:06