Search code examples
angulareventemitter

Component not emitting value back to parent component


I've got a problem with one of my components, the issue is that it doesn't seem to emit the model when the model changes. It works for my other components just fine but with this one it doesn't work no matter what I do.

The select component:

import {Component, Input, Output, EventEmitter, OnInit, DoCheck} from 'angular2/core';

@Component({
  selector: 'form-select',
  templateUrl: './app/assets/scripts/modules/form-controls/form-select/form-select.component.html',
  styleUrls: ['./app/assets/scripts/modules/form-controls/form-select/form-select.component.css'],
  inputs: [
    'options',
    'callback',
    'model',
    'modelProperty',
    'optionProperty',
    'disabled',
    'allowEmpty',
    'label'
  ]
})

export class FormSelectComponent implements OnInit, DoCheck {
  @Input() model: any;
  @Output() onModelChange: EventEmitter<any> = new EventEmitter();

  private isOpen: boolean = false;
  private previousModel: any = null;

  ngOnInit() {

    // If no model is set and the select shouldn't be allowed empty, set the model to the first option
    if (!this.model && !this.allowEmpty) {
      this.model = this.options[0];
    }
    // If it should be allowed empty, set it to null which will add an empty class in the markup
    else if (this.allowEmpty) {
      this.model = null;
    }
  }

  ngDoCheck() {

    // Check if the model changes and emit it if it does
    if (this.previousModel !== this.model) {
      this.onModelChange.emit(this.model);
    }

    this.previousModel = this.model;
  }

  toggle() {

    if (this.disabled) {
      this.isOpen = false;

      return false;
    }

    this.isOpen = !this.isOpen;
  }

  close() {
    this.isOpen = false;
  }

  select(option) {
    this.model = option;
    this.close();

    this.callback ? this.callback() : false;
  }

  isSelected(option) {
    return option[this.modelProperty] === this.model[this.modelProperty];
  }
}

When I check the value with pre the value stays the same despite the model changing inside the component:

<div class="col-xs-12 m-b-xxs">
  <pre>{{user.country}}</pre>
  <form-select [(model)]="user.country" modelProperty="country" [options]="countries" optionProperty="country" label="Country"></form-select>
</div>

What am I doing wrong?


Solution

  • There is a redundant on

    @Output() onModelChange: EventEmitter<any> = new EventEmitter();
    

    should be

    @Output() modelChange: EventEmitter<any> = new EventEmitter();
    

    For the shorthand two-way-binding syntax [(...)] the names of the properties (input and output) need to be identical except the Change suffix for the output.