Jose the hose
Jose the hose

Reputation: 1895

Add animation when expression value changes - Angular 5

I have an expression on a page called 'pointsBalance' that displays numeric value. Its hooked up to an observable, and when pointsBalance value goes up, I want to change the colour to green then back to its original colour, and red if it goes down in value. I thought I could use Angular 5 new animation aliases :increment and :decrement but I've been having problems with it.

HTML to display the points balance:

<div [@valueAnimation]="pointsBalance">{{ pointsBalance }}</div> 

Code that sets the animation and the pointsBalance observable:

import { Component, OnInit, Input } from '@angular/core';
import { trigger, style, transition, animate, keyframes, query, 
    stagger, state, group } from '@angular/animations';
import { CompetitionsService } from "../../../shared/index";
@Component({
  selector: 'points',
  templateUrl: './...html',

  animations: [
    trigger('valueAnimation', [
      transition(':increment', group([
        query(':enter', [
          style({ color: 'green', fontSize: '50px' }),
          animate('0.8s ease-out', style('*'))
        ])
      ])),
      transition(':decrement', group([
        query(':enter', [
          style({ color: 'red', fontSize: '50px' }),
          animate('0.8s ease-out', style('*'))
        ])
      ]))
    ])
  ]
})
export class CompetitionDetailsComponent implements OnInit {

  pointsBalance: number;

  constructor(private competitionsService: CompetitionsService, ) { }

  ngOnInit() {

    this.competitionsService.updatePointsBalance$.subscribe(
      (pointsBalance) => {
        this.pointsBalance = pointsBalance;
      }
    )
  }
}

And when pointsBalance value changes I get this console error:

ERROR Error: Unable to process animations due to the following failed trigger transitions @valueAnimation has failed due to:

  • query(":enter") returned zero elements. (Use query(":enter", { optional: true }) if you wish to allow this.)

Does anyone know why I'm getting this error? Or is there another way to achieve this? Thanks.

Upvotes: 8

Views: 10234

Answers (3)

I'm just going to paste the code as it would look, as Benjamin Kindle said, I tried it and it worked:

animations: [
    trigger('valueAnimation', [
      transition(':increment', [
          style({ color: 'green', fontSize: '50px' }),
          animate('0.8s ease-out', style('*'))
        ]
      ),
      transition(':decrement', [
          style({ color: 'red', fontSize: '50px' }),
          animate('0.8s ease-out', style('*'))
        ]
      )
    ])
  ]

Upvotes: 2

Benjamin Kindle
Benjamin Kindle

Reputation: 1844

the :enter animation will only animate elements that are newly created. Your "hacky" workaround works because it forces the inner span to get recreated whenever the value changes. I think what you want is to remove the :enter query. You want to animate when the number is in/decremented, and your animation has nothing to do with elements being added.

Upvotes: 3

Jose the hose
Jose the hose

Reputation: 1895

I found a fix from here and here.

<div [@valueAnimation]="pointsBalance"><span *ngFor="let pointsBalance of [ pointsBalance ]">{{ pointsBalance }}</span></div>

Feels a bit hacky though.

Upvotes: 2

Related Questions