0

I'm doing this:

<body>
    <div ng-controller="PresentationCtrl">
        <a href="" ng-click="findAll()">Find</a>
        <div>
            <ul class ="unstyled">
                <li ng-repeat="p in presentations">
                    <img ng-src="{{p}}" alt="presentation">
                </li> 
            </ul>
        <div>
    </div>
</body>

I have one placeholder element inside of presentations that is set when the function PresentationCtrl is hit.

When the findAll link is hit, I add an element to the array like so: $scope.presentations.push(sUrl);

But, when viewing my page, the list doesn't grow.

Does ng-repeat only fire once, or something? Can I force it to "refresh" and display the current values in presentations?

Here's my controller

The console.log before I push the element into the array gets hit. and displays the string that I expect.

function PresentationCtrl($scope){
$scope.presentations = ["http://angularjs.org/img/AngularJS-small.png"];

$scope.findAll = function(){
    var socket=null;
    socket = io.connect('http://[server]:3000');
    socket.on('handshake',function(){
        socket.emit('viewAll',{tenant:'qa'});
        socket.on('returnAll',function(back){
            for(i=0;i<back.length;i++){
                for(j=0;j<back[i].slides.length;j++){
                    socket.emit('signUrl',(back[i].slides[j].location));
                    break;
                }
            }
            socket.on('signedUrls',function(sUrl){
                console.log("back from signedUrls" + sUrl);
                $scope.presentations.push(sUrl);
            });
        });
    });
};
}

1 Answers1

1

it works fine.

http://plnkr.co/edit/agadSBFgz8YhWuDTtCPx?p=preview

Your situation might be different.

--------- EDIT ---------

ok, I got your situation. You are running a function not under watch of AngularJS. Thus, AngularJS does not know that your variable is changed, basically $digest is not called.

To mimic native Javascript asynchronous call, I use setTimeout.

The following code does not work. It change the value, but it won't be watched.

setTimeout( function() {
  $scope.presentations = [6,7,8,9];
}, 1000);

However this code does work. It change the value as expected

$timeout( function() {
  $scope.presentations = [6,7,8,9];
}, 1000);

The difference between setTimeout and $timeout is that $timeout is running under watch of AngularJS. Thus to make it work, you need to run $scope.apply() after it, or within it as a function.

This code does work with setTimeout.

setTimeout( function() {
  $scope.presentations = [6,7,8,9];
  $scope.$apply();
}, 1000);

Can't explain all to you in detail because I don't really mastered the AngularJS code.

This blog has a very good explanation about why we need to run $apply.

http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Just for the tip, to get the answer quickly, it's better to have a simplified example in jsfiddle or plunkr.
I know $http call cannot be demoed in plunkr or jsfiddle, but you can mimic your situation using setTimeout. It can make your situation understandable to readers most of time.

allenhwkim
  • 27,270
  • 18
  • 89
  • 122