Angular 2: Callback when ngFor has finished

Viewed 43298

In Angular 1 I have written a custom directive ("repeater-ready") to use with ng-repeat to invoke a callback method when the iteration has been completed:

if ($scope.$last === true)
{
    $timeout(() =>
    {
        $scope.$parent.$parent.$eval(someCallbackMethod);
    });
}

Usage in markup:

<li ng-repeat="item in vm.Items track by item.Identifier"
    repeater-ready="vm.CallThisWhenNgRepeatHasFinished()">

How can I achieve a similar functionality with ngFor in Angular 2?

8 Answers

The solution is quite trivial. If you need to know when ngFor completes printing all the DOM elements to the browser window, do the following:

1. Add a placeholder

Add a placeholder for the content being printed:

<div *ngIf="!contentPrinted">Rendering content...</div>

2. Add a container

Create a container with display: none for the content. When all items are printed, do display: block. contentPrinted is a component flag property, which defaults to false:

<ul [class.visible]="contentPrinted"> ...items </ul>

3. Create a callback method

Add onContentPrinted() to the component, which disables itself after ngFor completes:

onContentPrinted() { this.contentPrinted = true; this.changeDetector.detectChanges(); }

And don't forget to use ChangeDetectorRef to avoid ExpressionChangedAfterItHasBeenCheckedError.

4. Use ngFor last value

Declare last variable on ngFor. Use it inside li to run a method when this item is the last one:

<li *ngFor="let item of items; let last = last"> ... <ng-container *ngIf="last && !contentPrinted"> {{ onContentPrinted() }} </ng-container> <li>

  • Use contentPrinted component flag property to run onContentPrinted() only once.
  • Use ng-container to make no impact on the layout.
Related