5

Need to trigger animation every time the array changes

I am currently iterating over an array of products using *ngfor and everytime the length changes the animation will trigger. I am using Angular 4.

<ul class="items col col-md-12" *ngIf="hasProducts()" [@productsIntro]="products.length">

The issue is that I need the animation to trigger everytime the array changes at all and not just the length of the array. Sometimes the array length will be the same but the items in the array are different so the animation will not trigger.

I am not sure on how to pull this off and was hoping someone could help me out with a solution.

<ul class="items col col-md-12" *ngIf="hasProducts()" [@productsIntro]="products.length">
    <li class="col col-xs-12 col-sm-12 col-md-4" *ngFor="let product of products">
      <div class="item">
        <a href="" class="product-name">{{product.product_name}}</a>
        <div class="image-and-info col col-xs-8 col-sm-8 col-md-12">
          <div class="product-thumb">
            <img src="../../assets/img-filler.png" alt="{{product.product_name}}">
          </div>
          <div class="info">
            <div class="sku">SKU: {{product.sku}}</div>
            <div class="price">Price: {{product.price | currency:'USD':true:'1.2-2'}}</div>
          </div>
        </div>
        <div class="product-col col col-xs-4 col-sm-4 col-md-12">
          <div class="btn-group" role="group" aria-label="Basic example">
            <button type="button" class="btn btn-solid" (click)="viewProduct(product)">View Product</button>
            <button type="button" class="btn btn-solid add-to-cart" (click)="addToCart($event)">Add to Cart</button>
          </div>
        </div>
      </div>
    </li>
  </ul>

trigger form component:

trigger('productsIntro', [
  transition('* => *', [
    query(':enter', style({ opacity: 0 }), {optional: true}),
    query(':enter', stagger('100ms', [
      animate('1s ease-in', keyframes([
        style({opacity: 0, transform: 'translateY(-10%)', offset: 0}),
        style({opacity: .5, transform: 'translateY(10px)',  offset: 0.3}),
        style({opacity: 1, transform: 'translateY(0)',     offset: 1.0}),
      ]))]), {optional: true})
  ])
])
8
  • "the items in the array are different" : What are the changes on the items ? What makes them change ? Commented Nov 7, 2017 at 19:11
  • products are added and removed based on what category buttons the user clicks on. so every time the user clicks on a new category button the products array will change. Commented Nov 7, 2017 at 19:17
  • I think if you use states, you could trigger the animation both when products.length changes and when you click anywhere to make changes on the items Commented Nov 7, 2017 at 19:28
  • I read into the states and still a little confused on how to implement into my code. Looking at the Angular docs for animations I see they are using [@heroState]="hero.state" but I am not sure where the hero.state is referring to. I am still new to Angular so please excuse me if I am missing the obvious. Commented Nov 7, 2017 at 19:38
  • Currently, i having my animations switching every time the array changes but it does not work the first time I show the products on the list. Ended up doing [@productsIntro]="animationState" on HTML component. and using a toggle function every time I change the array to change the value of animationState. It should work the first time I load the array but it doesn't which is confusing. Commented Nov 7, 2017 at 19:42

1 Answer 1

4

Found out the animation was not being triggered when the products array length starts from 0 and then changes. My solution was to remove a conditional in the HTML component and add toggle function to change variable state everytime the array was changed:

Toggle Function:

animationState = 'inactive';
toggleState() {
this.animationState = this.animationState === 'active' ? 'inactive' : 'active';

}

changed from:

<ul class="items col col-md-12" *ngIf="hasProducts()" [@productsIntro]="animationState">
    <li class="col col-xs-12 col-sm-12 col-md-4" *ngFor="let product of products">

changed to:

<ul class="items col col-md-12"  [@productsIntro]="animationState">
    <li class="col col-xs-12 col-sm-12 col-md-4" *ngFor="let product of products">
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your solution, Can you make a StackBlitz example and let us know how you trigger toggle method
solution works fine, but previously rendered element still show with animation on screen after newly rendered array and take more time than actual to call done method, please help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.