0

I am trying to figure out how to call a function on the last iteration of an ng-repeat? I am using nested ng-repeats to display results in table format and would like to call a function after all the table cells are loaded.

I was trying to do something like this:

<tr ng-repeat="(rowIndex, rowResults) in chunkedResults">    
    <td ng-repeat="result in rowResults">
        <canvas id="item{{rowIndex}}{{$index}}"></canvas>
        <div>Canvas{{rowIndex}}{$index}}</div>
    </td>
    <div ng-if="$last" ng-init="loadCanvases()"></div>
</tr>

But with nested ng-repeats this does not seem to work. When there is only one ng-repeat present like so:

<tr>    
    <td ng-repeat="result in rowResults">
        <canvas id="item{{$index}}"></canvas>
        <div>Canvas{$index}}</div>
        <div ng-if="$last" ng-init="loadCanvases()"></div>
    </td>
</tr>

Then the function gets called on the last iteration as it should.

Any ideas why?

Cumulo Nimbus
  • 8,785
  • 9
  • 47
  • 68

3 Answers3

1

Add condition in your ng-init

<td ng-repeat="result in rowResults">
    <canvas id="item{{$index}}"></canvas>
    <div>Canvas{{$index}}</div>
    <div ng-if="$last" ng-init="$last?loadCanvases():null"></div>
</td>
Haroon Yousuf
  • 504
  • 4
  • 9
0

You can create a directive and place it in your "last" div :

<td ng-repeat="result in rowResults">
    <canvas id="item{{$index}}"></canvas>
    <div>Canvas{{$index}}</div>
    <div ng-if="$last" data-onlast></div>
</td>

and then execute your own logic in your custom "onlast" directive.

(ng-init is only supposed to be used at the same level as ng-repeat, though you could make it work)

richardtz
  • 4,993
  • 2
  • 27
  • 38
0

You're probably not approaching your problem the right way.

If you want to execute code once the DOM contains all the list elements (for instance you want to get the pixel height of your element), you can simply do it after a $timeout. This will ensure the previous angular digestion is done and everything is on place in the DOM.

$timeout(function() {
  // Here execute anything you want after the list is loaded
});
floribon
  • 19,175
  • 5
  • 54
  • 66
  • I think you had the right idea, but lack some explanation. Checkout the link in the accepted answer – Cumulo Nimbus Jan 22 '15 at 17:47
  • I cannot give more explanation as a more specific answer would require a more specific use case, i.e. what does he wants to do in that last function call. I'm not a big fan of the answer your pointed out: better pass an actual function on this on-finish-render directive rather than relying on another layer of events. – floribon Jan 22 '15 at 18:17