Angular 2 One Way Binding Between Components

I would like to know why, one way binding in Angular 2, only works for string properties and not for array of strings for instance ?

I have a parent component and a child component... I pass the collection of strings and a string and, internally, I change them and the string property type is modified in the child component directive and not in the parent component directive (that's what I expect) but, when I modify the first element of the array, the change is reflected in both, the parent and the child templates...

Parent Component

names : Array<string> = [...]
name : string = "App Works";

Child Component

@Input("names") _names : Array<string>;
@Input("title") _name : string;

Parent Component Template

{{names | json}}
<app-person [names]="names" [title]="name">
  <p>Awesome !!!</p>
</app-person>

The expected behavior is that, if I try to modify the first element of the array in my child component directive, the change is not reflected in the parent but in the child component.

I'm learning and doing some tutorials in PluralSight...

Upvotes: 2

Views: 953

Answers (2)

Bruno Jo&#227;o
Bruno Jo&#227;o

Reputation: 5525

Javascript has a crazy way of handling function params. If you pass a string as param (or any primitive value), your function gets a copy of this string and any modification won't affect the original variable outside the function, only the copy inside of it.

This is what we expect in many languages, but for other types (non-primitive), the function does not get a copy of the param, it actually gets a reference to the original object and any modification done inside the function will alter the original object.

I think this is the cause of your problem.

To solve this, you can create a copy of the array. One way to do that is to serialize/unserialize your array to/from JSON:

function(myExternalArray) {
    let myLocalArray = JSON.parse(JSON.stringify(myExternalArray));
    // YOUR CODE HERE
}

Upvotes: 3

kemsky
kemsky

Reputation: 15251

This is expected since you are sharing the same instance. If don't want to share changes then you should clone array in child component.

Upvotes: 2

Related Questions