0

I am in the process of checking to make sure I'm getting certain values sent to one component from another via Angular's custom Output() and EventEmitter(). They are being sent from my first component's view like this:

<list [results]="results" 
    (sendLanguage)="onLanguageReceived($event)"
    (sendZipcode)="onZipcodeReceived($event)">
</list>

If I console log these values within a function in Angular's ngOnInit life cycle hook within the component receiving the values, I see the current state of the values printed to the console successfully. That looks like this:

ngOnInit() {
        this.sortByFilters(this.language, this.zipcode);
        console.log(this.sortByFilters(this.language, this.zipcode));
}

The full sortByFilters function looks like this:

sortByFilters(language, zipcode) {
    this.onLanguageReceived(language);
    this.onZipcodeReceived(zipcode);
    console.log('sortByFilters: ' + 'lang ' + language, 'zip ' + zipcode);
}

But because I also need to see the state of these values when a user clicks on the element, I have placed that same receiving function in the ngOnChanges life cycle hook:

ngOnChanges() {
        this.sortByFilters(this.language, this.zipcode);
        console.log(this.sortByFilters(this.language, this.zipcode));
}

However, this is not working as expected. When a user clicks on the relevant UI, the function within the ngOnChanges never triggers, and therefore the console log never happens after the initial OnInit run. Isn't this exactly the kind of scenario that ngOnChanges is designed to be used for? Am I missing something?

Rey
  • 1,393
  • 1
  • 15
  • 24

1 Answers1

1

From the documentation:

Angular calls its ngOnChanges() method whenever it detects changes to input properties of the component (or directive).

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges

The ngOnChanges only happens on input properties, not output properties.

In this example, I have an input and output. The input changes are tracked via the ngOnChanges. The event is tracked by way of its click event:

export class StarComponent implements OnChanges {
    @Input() rating: number;
    starWidth: number;
    @Output() ratingClicked: EventEmitter<string> =
        new EventEmitter<string>();

    ngOnChanges(): void {
        // Convert x out of 5 starts
        // to y out of 86px width
        this.starWidth = this.rating * 86 / 5;
    }

    onClick(): void {
        this.ratingClicked.emit(`The rating ${this.rating} was clicked!`);
    }
}

I have the complete example here: https://github.com/DeborahK/Angular2-GettingStarted

Matt
  • 74,352
  • 26
  • 153
  • 180
DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • Ahh, okay. Thanks, @DeborahK. Any idea what I could use in this situation instead? I will check the life cycle docs to see if there's a different one I can use. – Rey Apr 28 '17 at 20:49
  • You should be getting the events and write code when the events occur. You shouldn't need a lifecycle hook for this? – DeborahK Apr 28 '17 at 20:58
  • Right. This was my original thought as well. That's why I'm confused as to why this sortByFilters() function isn't running every time a new event triggers a value to be sent via Output from the originating component. I'll have to dig in to see if something else is at issue. – Rey Apr 28 '17 at 21:08