Non-Primitive Inputs in Angular 2
08 November 2016

Remember when I talked about how Inputs in Angular 2 can be tricky? Well it gets worse. Here are some points to keep in mind when passing non-primitive types as Inputs.

ngOnChange won't work

As I've mentioned before, Angular 2 uses dirty checking. This means that for non-primitive data types, it can only tell a change has occurred if the Input's memory address has changed. Thus, the ngOnChanges method will not be called.

Changes in the child component are reflected in the parent

Take this as an example:

1
2
3
4
5
export class Parent {
	private sample = {
		"text": "original"
	};
}
1
2
3
4
<parent>
	<child [sampleInput]="sample"></child>
	{{ sample.text }}
</parent>
1
2
3
4
5
6
7
export class Child {
	@Input() sampleInput;

	changeSample() {
		this.sampleInput.text = "changed";
	}
}

The idea, in words, is pretty simple, The sample object passed from the parent to the child can be changed by the changeSample method. And by changing the sampleInput object in the Child class, the changes are immediately seen on the sample object in the Parent class.

However, words and application are a completely different thing. I spent a good chunk of my afternoon earlier debugging, trying to identify why an object in a particular class had its data changed when it shouldn't have been. It took a while to conclude that it was because the object was passed onto another class, and it took even longer to find which particular class was changing it.