7

I had asked a similar question about updating a public property by the component where it is declared.

I realized that if the public property is of primitive type, it is quite possible to modify its value in the component where it has been declared. Here is a playground link to check that

contrariwise, if the public property is an array or an object, it is not possible to modify the array or the properties of the object in the component where it has been declared. Here is a playground link to check that.

I'd like to know if it's a bug or a design choice.

4

This is definitely a bug because according to documentation,

When you add a component in markup, you can initialize public property values in the component based on property values of the owner component. The data binding for property values is one-way. If the property value changes in the owner component, the updated value propagates to the child component.

The child component must treat property values passed from the owner component as read-only. If the child component tries to change a value passed from an owner component, you see an error in the browser console.

To trigger a mutation for the property value provided by the owner component, the child component can send an event to the parent. If the parent owns the data, the parent can change the property value, which propagates down to the child component via the one-way data binding.

Also in the same documentation, you will find example of todoapp and child comp todoitem, in which its clearly written that

Nothing happens in the UI! You see an error in the browser console saying that you can’t change the value of itemName. You can’t change itemName in c-todoitem because you can only set the value of a public property (@api) at component construction time.

So, whether the properties are complex or primitive data-types, @api public properties in child should not be allowed to be modified after the construction time when they are passed from parent component.

| improve this answer | |
6

As per documentation:

We recommend using primitive data types for properties instead of using object data types. Slice complex data structures in a higher-level component and pass the primitive values to the component descendants.

There are a few reasons that it’s better to use primitive values.

Primitive values require specific @api properties that clearly define the data shape. Accepting an object or an array requires documentation to specify the shape. If an object shape changes, consumers break.

Standard HTML elements accept only primitive values for attributes. When a standard HTML element needs a complex shape, it uses child components. For example, a table element uses tr and td elements. Only primitive types can be defined in HTML. For example, isn't a value in HTML, only in Lightning Web Components.

| improve this answer | |
  • 1
    Thanks @Atlas for the link but Salesforce has to update the doc because now it is indeed possible to modify the value of public property in the child component as you can see here – dibocor Oct 31 '19 at 13:46
  • Communication from parent to child properties is one-way as far as I know. Meaning you can actually change the value of the child property passed by the parent. Maybe there's something that breaks when it's a non primitive value which they are advising against on the docs. – Atlas Can Oct 31 '19 at 15:13
  • This answer does not really answer the question. I have shared why it is a bug here – salesforce-sas Oct 31 '19 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.