Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

i have this code and i can't see where is the source of problem, i don't get any error in the chrome console my controller :

function notifController($scope) {
  $scope.refreshMsgs = function () {
    $.post("notification-center-trait.aspx")
      .success(function (data) {
        $("#loadedthings").html(data);
        newMsgs = JSON.parse($("#label1").html());
        $scope.msgs = newMsgs;
      });
  }
  $scope.refreshMsgs();
}

label1 and label2 are loaded correctly inside a div loadedthings;

newMsgs in the console is parsed just the way it should;

i had it working for other pages but it seems that i missed something on this one.i have <html ng-app> tag :

<div ng-controller="notifController"> 
    <div class="row">
    {{msgs.length}} new msgs : 
              <table class="table">
                  <tbody >
                      <tr ng-repeat="msg in msgs">
                        <td>
                            {{msg.sender}}
                        </td>
                        <td>
                            {{msg.message}}
                        </td>
                        <td>
                            {{msg.date}}
                        </td>
                      </tr>
                  </tbody>
              </table>
</div>
</div>

i get 'undefined' in the console when i execute this : angular.element($0).scope()

share|improve this question
 
Are you sure $0 is working?. I don't know what you're doing with that... –  m59 22 hours ago
 
I tested your code and everything here is working fine. I suspect that you're messing with the DOM inappropriately and have made a mistake. Anything like angular.element belongs in a directive. Angular makes the scope property available wherever you need it, other than maybe rare exceptions, so you should not need to access an element or a scope this way. –  m59 21 hours ago
 
@m59 i've just executed angular.element($0).scope() in chrome console just to see what's happening in my scope link but i get 'undefined' –  saadzer 21 hours ago
 
As I said, with the code you have here, the controller is initialized and the data-binding is working. The problem you are having is not conveyed in this code. Just to be absolutely sure, do this: $scope.foo = 'test' and in your markup: {{foo}}. Perhaps your ajax call just isn't coming through? If the controller truly isn't working, something else (not in this code) is the issue. –  m59 21 hours ago
1  
What you just described isn't even valid.... that would have to be {{foo}}. You definitely have a simple error that you could debug with the console, I'm certain. Also, Angular has the $http for ajax calls, you should be using that rather than jQuery. –  m59 21 hours ago
show 4 more comments

1 Answer

up vote 3 down vote accepted

Disregarding other architectural issues I pointed out in the comments, the real issue is that you're using jQuery's ajax instead of Angular's $http. When you don't do things like that through Angular, you're working outside of Angular's scope and it doesn't know about changes. While not ideal, you can use $scope.$apply to let angular know something was updated outside of its knowledge. That would look like this:

$scope.$apply(function() {
  $scope.msgs = newMsgs;
});

That is telling Angular that you've modified something it needs to know about from a context that it doesn't know about (the jQuery ajax call in this case).

There are some valid uses of $scope.$apply(), such as in event handlers, but most other times it is a sign of bad practices. You should definitely be using Angular's $http for ajax calls.

share|improve this answer
 
As an addendum, $scope.$apply can throw errors if you use it at the wrong time (you can't just put it everywhere you're misbehaving, as a solution to them all), however, $timeout (an Angular wrapper for setTimeout) will behave all the time, and make sure that your changes end up in the next $apply pass (which is where they would have landed anyway). It shouldn't be abused, but it's safer than $apply, without dirty hacks in directives, to check if it's safe/needed or not. –  Norguard 19 hours ago
 
@Norguard True...but if you are ever using $apply in a place that it throws an error, it shouldn't be used at all. That's a huge code smell. Like I said, $apply is usually not needed at all unless you're using events or third-party libraries. –  m59 19 hours ago
1  
absolutely. But some of those third-party libraries are half-sync, half-async, and others go down their own rabbit-holes of pub/sub or setTimeout, or just require you to dance around them in those circles, yourself. I know first-hand that if you're not careful, both MasonryJS (for pinterest/infinite-tumble layouts) and D3JS (for making tweenable SVG graphs) can both provide their share of misery with if (!$scope.$rootScope.$$phase) nonsense, if Angular is only partially tied into the process (like calling Msnry.stamp + Msnry.layout on an ng-repeat ...). $timeout is then very elegant. –  Norguard 18 hours ago
 
@Norguard Ah, good addition! –  m59 9 hours ago
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.