av0000
av0000

Reputation: 1967

Angular 2 Animations - Transitioning between two states won't trigger

I'm trying to get the example from the Angular Documentation (specifically the Transitioning between two states section) and can't get the animation to trigger. I am not getting any errors and don't understand where I'm going wrong.

Here is my code:

Html

<ul>
    <li *ngFor="let hero of heroes"
        [@heroState]="hero.state"
        (click)="toggleState()">
      {{hero.name}} - {{hero.state}}
    </li>
</ul>

TS

import { Component, OnInit, trigger, state, animate, transition, style  } from '@angular/core';

@Component({
  selector: 'app-coating',
  templateUrl: './coating.component.html',
  styleUrls: ['./coating.component.css'],
  animations: [
    trigger('heroState', [
      state('inactive', style({
        backgroundColor: '#eee',
        transform: 'scale(1)'
      })),
      state('active',   style({
        backgroundColor: '#cfd8dc',
        transform: 'scale(1.1)'
      })),
      transition('inactive => active', animate('100ms ease-in')),
      transition('active => inactive', animate('100ms ease-out'))
    ])
  ]
})

export class CoatingComponent implements OnInit{

  state:string;
  toggle: boolean = true;
  name: string;

  toggleState() {
    console.log('Test');
    this.toggle = !this.toggle;
    console.log(this.toggle);
    this.state = this.toggle ? 'inactive':'active';
  }

  heroes = [
    { id: 11, name: 'Mr. Nice', state: 'inactive' },
    { id: 12, name: 'Narco', state: 'active'  },
    { id: 13, name: 'Bombasto', state: 'inactive'  },
    { id: 14, name: 'Celeritas', state: 'active'  },
    { id: 15, name: 'Magneta' },
    { id: 16, name: 'RubberMan' },
    { id: 17, name: 'Dynama' },
    { id: 18, name: 'Dr IQ' },
    { id: 19, name: 'Magma' },
    { id: 20, name: 'Tornado' }
  ];

  constructor() {
   
  }
  
  ngOnInit(){}

}

Also for the the console.log, when I click on the first hero I get:

Test
true
inactive

Upvotes: 1

Views: 1719

Answers (1)

John Siu
John Siu

Reputation: 5092

Issue

The toggleState() need to pass back something to indicate which hero's state to toggle.

I add index in the *ngFor body, and use index(i) as the parameter.

html

<ul>
    <li *ngFor="let hero of heroes; let i = index"
        [@heroState]="hero.state"
        (click)="toggleState(i)">
      {{hero.id}} - {{hero.name}} - {{hero.state}}
    </li>
</ul>

ts

import { Component, OnInit, trigger, state, animate, transition, style } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
    trigger('heroState', [
      state('inactive', style({
        backgroundColor: '#eee',
        transform: 'scale(1)'
      })),
      state('active', style({
        backgroundColor: '#cfd8dc',
        transform: 'scale(1.1)'
      })),
      transition('inactive => active', animate('100ms ease-in')),
      transition('active => inactive', animate('100ms ease-out'))
    ])
  ]
})
export class AppComponent implements OnInit {

  state: string; // not used
  toggle: boolean = true; // not used
  name: string; // not used

  heroes = [
    { id: 11, name: 'Mr. Nice', state: 'inactive' },
    { id: 12, name: 'Narco', state: 'active' },
    { id: 13, name: 'Bombasto', state: 'inactive' },
    { id: 14, name: 'Celeritas', state: 'active' },
    { id: 15, name: 'Magneta', state: 'active' },
    { id: 16, name: 'RubberMan', state: 'active' },
    { id: 17, name: 'Dynama', state: 'active' },
    { id: 18, name: 'Dr IQ', state: 'active' },
    { id: 19, name: 'Magma', state: 'active' },
    { id: 20, name: 'Tornado', state: 'active' }
  ];

  constructor() { }

  ngOnInit() { }

  toggleState(i) {
    console.log(this.heroes[i].name, this.heroes[i].state);
    this.heroes[i].state = (this.heroes[i].state === 'active' ? 'inactive' : 'active');
    console.log(this.heroes[i].name, this.heroes[i].state);
  }

}

Upvotes: 2

Related Questions