ng-lottie icon indicating copy to clipboard operation
ng-lottie copied to clipboard

Does ng-lottie destroy the animation after the component is destroyed?

Open nikhilmathew opened this issue 6 years ago • 4 comments

there is a destroy method in the lottie-web library but it is not called anywhere in ng lottie

nikhilmathew avatar Oct 26 '18 12:10 nikhilmathew

According to my debugging, it doesn't. I ended up attaching a directive of my own that invokes destroy() upon the directive's ngOnDestroy.

robsman avatar Oct 18 '19 20:10 robsman

@robsman how did your code do it?

Snowbases avatar Jan 26 '20 13:01 Snowbases

@SnowBases Not OP, but I've had to do the same today, so I hope this helps: You can use ng-lottie's animCreated property to pass it a function that is called by ng-lottie after it has initialized the animation with a reference to the lottie animation object. Use this to store a reference to the animation object in your component, and call animation.destroy() in ngOnDestroy.

Template: <lottie-animation-view (animCreated)="handleAnimation($event)" [options]="options" />

Component:

 ...
  private animation: any;

  handleAnimation(animation) {
    this.animation = animation;
  }

  ngOnDestroy() {
    if (this.animation) {
       this.animation.destroy();
    }
}
...

It would be nice if ng-lottie would do that by itself automatically. I might add a pull request for this in the near future (should be a straight-forward change).

steffinchen avatar Jan 30 '20 16:01 steffinchen

@SnowBases I basically did the same as @steffinchen, but wrapped it into a directive for reuse. Each of our lotties then reads like this: <lottie-animation-view tiLottieCleanup ...

import {Directive, OnInit, OnDestroy, ViewContainerRef, EventEmitter, Input} from '@angular/core';

/**
 * Lifecycle directive that properly destroys lottie animations upon destruction of lottie-animation-view components
 */
@Directive({selector: '[tiLottieCleanup]'})
export class LottieCleanupDirective implements OnInit, OnDestroy {

  lottieAnimations = [];

  @Input()
  lottieName: string = '';

  constructor(private vcRef: ViewContainerRef) {}

  ngOnInit() {
    if (this.vcRef['_data'] && this.vcRef['_data'].componentView) {
      const component = this.vcRef['_data'].componentView.component;
      if (component && component.animCreated instanceof EventEmitter) {
        component.animCreated.subscribe((lottieAnimation) => {
          this.lottieAnimations.push(lottieAnimation);
        });
      }
    }
  }

  ngOnDestroy() {
    console.log(`About to destroy ${this.lottieAnimations.length} lottie animation(s) ...`);

    for (const lottieAnimation of this.lottieAnimations) {
      try {
        lottieAnimation.destroy();
      } catch (err) {
        console.log('Failed destroying lottie animation', err);
      }
    }
    this.lottieAnimations.length = 0;
  }
}

robsman avatar Jan 31 '20 08:01 robsman