2

I want to use the ng-repeat directive to bind some data to a div. though the call is successful and i am getting the data and storing it in a scope variable im anot able to use the ng-repeat to display it

     <div data-ng-app="myapp" id="sidestatus" style="position:fixed;top:50%;right:0;height:200px;width:200px;background-color:red;" data-ng-controller="myctrl">//wont bind here after successful execution
             <ul>
                 <li data-ng-repeat="x in obj">
                      {{x.heading+' '+x.id+' '+x.name }}
                 </li>
            </ul>
      </div> 

my javascript

 var app = angular.module("myapp", []);
 app.controller("myctrl", function ($scope, $http) {
     var obj2=new Array();
     $.ajax({
         type: "POST",
         url: "NotifierService.asmx/getdata",
         data: {},
         contentType: "application/json; charset=utf-8",
         dataType: "json",
         success:function (response) {
             var res = response.d;
             var res4 = res.split(",");
             for (var i = 0; i < res4.length; i++) {
                 var res2 = res4[i].split(":");
                 obj2[i] = {}
                 obj2[i].heading = res2[0];
                 var res3 = res2[1].split("/");
                 obj2[i].id = res3[0];
                 obj2[i].name = res3[1];
             }
             $scope.obj = obj2; 
            //successfully execute the success function everytime
          },
          error:function () { alert("failure");}
     });
 });

data being sent

           "heading1:23/name1,heading2:24/name2"
tasty_snack
  • 174
  • 2
  • 8
Sujit.Warrier
  • 2,815
  • 2
  • 28
  • 47
  • 3
    Why do you use the jquery ajax function instead of the angular $http service? YOu even inject $http in your controller, why not use it? – LionC Jul 08 '15 at 10:51
  • 1
    well when i tried using $http it says that the url is not found but withajax function im getting the data – Sujit.Warrier Jul 08 '15 at 10:52
  • Then I would start to look into that, I can guarantee you that $http works, so something with your code is wrong – LionC Jul 08 '15 at 10:58
  • 1
    its a web method which returns data from database. does that make any difference? thats what im trying to call using ajax – Sujit.Warrier Jul 08 '15 at 11:03
  • 1
    don't use `jquery` ajax if ur using `angularjs` use `$http` service in angularjs – Kalhan.Toress Jul 08 '15 at 11:03
  • i tried using $http.get but i get the error get "NotifierService.asmx/getdata" 404 not found but using $.ajax is working and im getting the data – Sujit.Warrier Jul 08 '15 at 11:08

3 Answers3

8

Whenever you execute some code outside AngularJS "controlled" functions, AngularJS doesn't know if something may have change in any of the scopes, and because of this it don't try to find the changes and modify the presentation with the changes if there are any.

In your code, you are making an Ajax call with jQuery. The callback of that Ajax call is executed outside of AngularJS controlled code and it happens what I explained previously. So what you have to do is inform AngularJS that something may have changed in the scope. You have two options to do this.

$scope.$digest() is used to tell AngularJS to check for changes. So you're code could look something like this:

success:function (response) {
  var res4 = res.split(",");
  var res = response.d;
  for (var i = 0; i < res4.length; i++) {
     //... 
  }
  $scope.obj = obj2; 
  $scope.$digest(); //hey AngularJS, look for changes to update the scope!
}

Another way is to use $scope.$apply. This method tells AngularJS to execute the function passed as an argument and afterwards (whether the function executed correctly or not, throwing and error for example) check for changes in the scopes. So your code could look something like:

success:function (response) {
  $scope.$apply(function() {  //hey AngularJS, execute this function and update the view!
     var res = response.d;
     var res4 = res.split(",");
     for (var i = 0; i < res4.length; i++) {
         //...
     }
     $scope.obj = obj2;
  })
}
  • 1
    Even though this works, using $http instead of jQuery is a lot cleaner and completely erases the need to touch $scope. I would always recommend to write code the way it is meant to be written (which is $http) – LionC Jul 08 '15 at 12:03
  • 1
    I agree with @LionC that is cleaner to use $http, even more, if possible it's convenient to avoid any use of jQuery at all. However, many times you have to interact with third party libraries that may have callbacks that will be executed outside AngularJS and it's important to be aware of it and know how to "return back to AngularJS execution scope". – Gonzalo Ruiz de Villa Jul 08 '15 at 12:13
1

Like @LionC mentioned, you should look into why $http throws an error.

You can try to do:

success: function () {
    $scope.$evalAsync(function () {
        var res = response.d;
        var res4 = res.split(",");
        for (var i = 0; i < res4.length; i++) {
            var res2 = res4[i].split(":");
            obj2[i] = {}
            obj2[i].heading = res2[0];
            var res3 = res2[1].split("/");
            obj2[i].id = res3[0];
            obj2[i].name = res3[1];
       }
       $scope.obj = obj2; 
    });
}

But I thoroughly recommend you do not! More info here: "Thinking in AngularJS" if I have a jQuery background?

Hope this helps!

Plunk demo : http://embed.plnkr.co/YWQ1LyZWm2fzwgPxX4kk/preview

The essential use of $scope.$evalAsync is to get angular to apply the changes in scope to the DOM. There are other ways to do this too : http://www.panda-os.com/2015/01/angularjs-apply-digest-and-evalasync/#.VZ0JIPmqqko

Hope this helps!

Community
  • 1
  • 1
tasty_snack
  • 174
  • 2
  • 8
  • @Mysterio11 I added an edit, does it work out now? it works in the demo! – tasty_snack Jul 08 '15 at 11:44
  • 1
    it started working using the $scope.$digest function as suggested by Gonzalo Ruiz de Villa. but thanks for trying :) – Sujit.Warrier Jul 08 '15 at 11:50
  • By the by, that panda link now goes to some really annoying malware site. Helpful tip on the malware site: Use Task Manager to minimize the window. Then you can kill it. To recover your lost tabs, turn off javascript in Chrome and then do the History > Recently Closed thing. With javascript off, you can close the malware window and keep the rest of your tabs. – user1664043 Jun 14 '16 at 16:32
0

Using availsync function may solve the problem. If not, try to use settimeout. Its just because of two way binding problem.

Ajay2707
  • 5,690
  • 6
  • 40
  • 58
  • 3
    Consider actually explaining something. In this form, this answer is not useful – LionC Jul 08 '15 at 10:57
  • there is no timeout problem im getting the data the call is sucessfull im also putting the data is $scope.obj but the repeat directive is not picking it up – Sujit.Warrier Jul 08 '15 at 10:57
  • use availsync function because i faced lot of issues like this and most of them solved by using availsync function. – venkatesh thigala Jul 08 '15 at 11:03