0

I have the following properties in an lwc component:

editPropertiesMap = new Map(); editPropertiesView = []; 

I have a function that edits values in editPropertiesMap, and at the end runs the following:

this.editPropertiesView = [...this.editPropertiesMap].map(([key, value]) => ({ key, value })); 

This is how its used in HTML:

<template> <lightning-layout multiple-rows pull-to-boundary="small"> <template if:true={editPropertiesView}> <template for:each={editPropertiesView} for:item="prop"> <template if:true={prop.value.availableForEdit}> <lightning-layout-item size="12" key={prop.key}> <c-edit-property obj={prop.value}></c-edit-property> </lightning-layout-item> </template> </template> </template> </lightning-layout> </template> 

The child components simply contains @api obj and it shows the values in some text box.

Every time i update editPropertiesView, i excpet the html to be re-rendered and that all of the child components will use the new values.

However, the values are not changed and i have no idea why.

Child component:

@api obj; @track currentObj; connectedCallback() { this.currentObj = JSON.parse(JSON.stringify(this.obj)); } 

HTML:

<template> <lightning-layout> <template if:true={currentObj}> <lightning-layout-item size={currentObj.size} padding="around-small" class="paddingEditPanel"> <lightning-input data-id={id} date-style="short" type={currentObj.type} value={currentObj.value} checked={currentObj.value} label={currentObj.label} onchange={handleInputChange} disabled={isDisabled}> </lightning-input> </lightning-layout-item> </template> </lightning-layout> </template> 

Based on some suggestions i googled:

  • i tried to add @track
  • i tried do a shallow copy like this: this.editPropertiesView = [...this.editPropertiesView]

nothing works, please advise.

1 Answer 1

0

Firstly, the LWC has difficulties to see the change in the mapped value. Therefore I suggest to use a copy of individual values:

this.editPropertiesView = [...this.editPropertiesMap].map(([key, value]) => { value = { ...value }; return { key, value }; }); 

(This is only necessary, if values of the Map are changed and not just added and removed.)

Secondly, the connectedCallback of the child component is only executed once when the component is inserted in the DOM. In order to make the component reactive, I suggest a setter of the obj to set the currentObj (which then doesn't need a @track annotation):

currentObj = {text: 'No data'}; @api get obj() { return this.currentObj; } set obj(value) { if (value) { this.currentObj = JSON.parse(JSON.stringify(value)); } else { this.currentObj = {text: 'No data'}; } } 

In my example code I used a property "text", but you are likely to read something else. (Are you sure you need to parse/stringify at all?!)

3
  • Hi Felix, pls ignore the last line, i edited your answer instead of my question by accident. I tried your solution but it didn't work. The child component is still not seeing the new values that were changed. i added the child cmp code, any more suggestions? Commented Mar 11, 2024 at 17:13
  • I've added information regarding the Javascript of the child component, which you added to your question. Commented Mar 11, 2024 at 20:36
  • Thanks a lot for the help! using a setter worked Commented Mar 12, 2024 at 8:29

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.