Search code examples
angulartypescripteventemitter

Emit custom event in Angular2 and TypeScript


In short, I have basically mocked this: http://learnangular2.com/outputs/

Here is what I do:

  1. Send Login Request using login.service.ts (axios module)
  2. Handle the form submit - if success route away else display modal with issue
  3. (in the case of issue) display ng2-bootstrap modal

So, I'll go ahead and verify that the API is working correctly, I can trigger a fail by sending bad creds, no problem. Now, I have a failure, I want to display a good looking modal explain what happened with a users request. The below is my login.component.ts

@Component({
  selector: 'login',
  encapsulation: ViewEncapsulation.None,
  styles: [require('./login.scss')],
  template: require('./login.html'),
  providers: [LoginService,LoginRouteGuard]
})
export class Login {

  public form:FormGroup;
  public email:AbstractControl;
  public password:AbstractControl;
  public submitted:boolean = false;
  private router:Router;
  @Output() authFailed = new EventEmitter();

  constructor(fb:FormBuilder, private loginService: LoginService, router: Router) {
    // ...stripping bc it doesnt really matter
  }

  public onSubmit(values:Object):void {
    this.submitted = true;
    if (this.form.valid) {
      this.loginService.post(this.email.value,this.password.value).then((token:string)=>{
        //store cookies/manage session then redirect
      },(err:Object)=>{
        if(err.response.status) this.authFailed.emit(err.response.status);
      });
    }
  }
}

Right, so from this perspective, I would need to bind my event to my child directive, so that I can be call from my child component. See the below

<form [formGroup]="form" (ngSubmit)="onSubmit(form.value)" class="form-horizontal">
    <!-- removed my form to shorten question -->
</form>
<message-modal (authFailed)="handleAuthFailure($event)"></message-modal>

No problem here, right? I have bound a custom event (ie authFailed) to the message-modal directive. Next step is to handle this event from my modal component. See the below

import { Component } from '@angular/core';

@Component({
  selector: 'message-modal',
  template: require('./modal.html'),
  styles: [require('./modal.scss')],
})
export class MessageModal{

    public content:Object = {header:'Message Modal' ,body:'Body Content'};

    constructor(){}

    public handleAuthFailure(code){
        console.log('DEBUG', code)
    }
}

So, from this point, I should be seeing a line in my console similar to "DEBUG 401" or something of that sort. No luck; this line is never called.


Solution

  • Event authFailed belongs to Login component, but you added listener to MessageModal - it wont work.

    In your case MessageModal is within Login component, so you could call it directly without events:

     //Login component
     @ViewChild(MessageComponent) message:MessageComponent
     ....
     (err:Object)=>{
        if(err.response.status) this.message.handleAuthFailure(err.response.status);
     });
     ....