title: Page transition animations with Angular 2.0 router and component interface promises
body: <p>In Angular 1.x we can use ngAnimate to detect when we are leaving or entering a particular route. Furthermore we are able to apply behaviors to them:</p>
  
  <pre><code>animateApp.animation('.myElement', function(){
  
      return {
  
          enter : function(element, done) {
              //Do something on enter
          },
  
          leave : function(element, done) {
              //Do something on leave
          }
      };
  
  )};
  </code></pre>
  
  <p>Resulting in a product like this: <a href="http://embed.plnkr.co/uW4v9T/preview" rel="noreferrer">http://embed.plnkr.co/uW4v9T/preview</a></p>
  
  <p>I would like to do something similar with Angular 2.0 and I feel like I'm pretty close... </p>
  
  <p>So here goes, I've created a simple router in the main application component that controls the navigation between the <em>home</em> and <em>about</em> components. </p>
  
  <pre><code>import { bootstrap, bind, Component, provide, View } from 'angular2/angular2';
  import {RouteConfig, RouteParams, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, APP_BASE_HREF, ROUTER_BINDINGS} from 'angular2/router'
  
  
  
  
  /////////////////////////////////////////////////////////////////
  // Home Component Start
  /////////////////////////////////////////////////////////////////
  @Component({
    selector: 'home-cmp'
  })
  
  @View({
    template: `
      &lt;h2 class="title"&gt;Home Page&lt;/h2&gt;
    `
  })
  
  class HomeCmp implements OnActivate, onDeactivate{
  
    onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
      console.log("Home Page - initialized");
    }
  
    onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
      console.log("Home Page - destroyed");
    }
  
  }
  /////////////////////////////////////////////////////////////////
  // Home Component End
  /////////////////////////////////////////////////////////////////
  
  
  
  
  /////////////////////////////////////////////////////////////////
  // About Component Start
  /////////////////////////////////////////////////////////////////
  @Component({
    selector: 'about-cmp'
  })
  
  @View({
    template: `
      &lt;h2 class="title"&gt;About Page&lt;/h2&gt;
    `
  })
  
  class AboutCmp implements OnActivate, onDeactivate {
  
    onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
      console.log("About Page - initialized");
    }
  
    onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
      console.log("About Page - destroyed");
    }
  
  }
  /////////////////////////////////////////////////////////////////
  // About Component End
  /////////////////////////////////////////////////////////////////
  
  
  
  
  /////////////////////////////////////////////////////////////////
  // Main Application Componenent Start
  /////////////////////////////////////////////////////////////////
  @Component({
    selector: 'my-app'
  })
  
  @View({
    template: `
      &lt;div&gt;
        &lt;h1&gt;Hello {{message}}!&lt;/h1&gt;
        &lt;a [router-link]="['./HomeCmp']"&gt;home&lt;/a&gt;
        &lt;a [router-link]="['./AboutCmp']"&gt;about&lt;/a&gt;
        &lt;hr&gt;
        &lt;router-outlet&gt;&lt;/router-outlet&gt;
      &lt;/div&gt;
    `,
    directives: [ROUTER_DIRECTIVES]
  })
  
  @RouteConfig([
    {path: '/', component: HomeCmp, as: 'HomeCmp'},
    {path: '/about', component: AboutCmp, as: 'AboutCmp'}
  ])
  
  export class App {
  }
  /////////////////////////////////////////////////////////////////
  // Main Application Componenent End
  /////////////////////////////////////////////////////////////////
  
  
  
  
  bootstrap(App, [
    ROUTER_BINDINGS,
    ROUTER_PROVIDERS,
    ROUTER_DIRECTIVES,
    provide(APP_BASE_HREF, {useValue: '/'})
  ])
  </code></pre>
  
  <p>At the moment I am able to capture when the router has instantiated or destroyed a particular component when it moves from one to the next. This is great, but when the the <em>previous</em> component is <em>destroyed</em> I am not able to apply an <em>on leave</em> transition animation before the next component is initialized. </p>
  
  <pre><code>class HomeCmp implements OnActivate, onDeactivate{
  
      onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
          //This works
          TweenMax.fromTo($(".title"), 1, {opacity: 0}, {opacity: 1});
      }
  
      onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
          //This get ignored
          TweenMax.fromTo($(".title"), 1, {opacity: 0}, {opacity: 1});
      }
  
  }
  </code></pre>
  
  <p>It seems like there is a solution to this using promises. Angular.io's API preview they state:</p>
  
  <p><strong>If onDeactivate returns a promise, the route change will wait until the promise settles.</strong> </p>
  
  <p>and</p>
  
  <p><strong>If onActivate returns a promise, the route change will wait until the promise settles to instantiate and activate child components.</strong> </p>
  
  <p><a href="https://angular.io/docs/ts/latest/api/" rel="noreferrer">https://angular.io/docs/ts/latest/api/</a></p>
  
  <p>I am super brand new to promises so I mashed this together into my code which solved the problem of my current component being destroyed on initialization of the next one, but then it <em>never</em> gets destroyed, it only creates a new instance of it. Every time I navigate back to it, it will create a new instance resulting in multiple copies.</p>
  
  <pre><code>onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
  
      function ani(){
        TweenMax.fromTo($(".title"), 1, {opacity: 1}, {opacity: 0});
      }
  
      var aniPromise = ani();
  
      aniPromise.then(function (ani) {
          ani();
      });
  
  }
  </code></pre>
  
  <p>So to recap, the router should be able to wait for the current component to finish it's <em>business</em> before destroying it and initializing the next component.</p>
  
  <p>I hope that all makes sense and I really appreciate the help!</p>