Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

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 Jan 15 '14 at 1:54
    
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 Jan 15 '14 at 2:00
    
@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' – zerzer Jan 15 '14 at 2:01
    
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 Jan 15 '14 at 2:05
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 Jan 15 '14 at 2:50

1 Answer 1

up vote 16 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 Jan 15 '14 at 4:41
    
@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 Jan 15 '14 at 4:53
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 Jan 15 '14 at 5:07
    
@Norguard Ah, good addition! – m59 Jan 15 '14 at 14:32

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.