23

I have a component with a sub component timeline.

<app-timeline [(editing)]="editingDate"></app-timeline>

In the timeline component I have these properties:

@Input() editing: boolean; // <--- detect change on this
@Output() editingChange = new EventEmitter();

How can I check when a change to the editing property occurs from the timeline component? I need to emit the editing value whenever it changes.

Should I use a setter for the editing property then emit from there?

private _editing
set editing() { ... // emit }

Or is there another way?

David Buck
  • 3,752
  • 35
  • 31
  • 35
matt
  • 659
  • 2
  • 8
  • 15
  • Refer : onChanges method, https://angular.io/api/core/OnChanges, this can get you which property is changed. – Abhishek Kumar Jan 19 '19 at 11:58
  • 3
    Possible duplicate of [How to detect when an @Input() value changes in Angular?](https://stackoverflow.com/questions/38571812/how-to-detect-when-an-input-value-changes-in-angular) – Abhishek Kumar Jan 19 '19 at 12:01
  • I'm trying to send data from a component up through 2 components would it be better to use a service or should I emit through the 2 components? – matt Jan 19 '19 at 12:18
  • making service is a better option. – Abhishek Kumar Jan 19 '19 at 13:23

2 Answers2

25

The ngOnChanges can be used exactly for this

First make sure your component implements the ngOnChanges like this

export class TimelineComponent implements OnChanges

Then implement the ngOnChanges method like this

ngOnChanges(changes: SimpleChanges) {
    if (changes.editing) {
        console.log(changes.editing.currentValue);
    }
}

Any time any input was changed it will enter the ngOnChanges method. This is also why the if statement was added since if any other input was changed the editing property won't exist on the changes object.

For primitive values it will trigger on any change. For reference values you need to change the actual reference, just changing a property of the object you have in the input won't work.

Maaddy
  • 618
  • 5
  • 13
Jelle
  • 2,026
  • 1
  • 12
  • 17
8

ngOnChanges looks for every change in the component lifecycle. Using it is kinda overkill.

You don't need two-way binding(again it's up to you and the requirement)

Just use property binding instead...

<app-timeline [editing]="editingDate"></app-timeline>

Whenever editing sets then you have to emit the Output()

@Output() editingChange = new EventEmitter();

public get editing(): boolean {
   return this._editing;
}

@Input()
public set editing(edit: boolean) {
    if (edit) {
        this._editing = edit;
        this.editingChange.emit("something");
    }
}
skdonthi
  • 1,308
  • 1
  • 18
  • 31