1

Could you please guide me how to make the wrapper class object reactive in LWC js.

I believe that @track properties are reactive but when I change the value of any property in this.coreAttributes js object, its not reflective in on Save button click

Js, Apex, Html file are given below

JavaScript

import { LightningElement, track, api } from "lwc";
import queryCoreAttributes from "@salesforce/apex/P1PlantInfoPromptSolar.queryCoreAttributes";

export default class P1PlantInfoPromptSolar extends LightningElement {
@track coreAttributes;

connectedCallback() {
    queryCoreAttributes()
    .then(result => {
      this.coreAttributes = JSON.parse(result);
    }) 
    .catch({

    });

    this.promptSpecificAttributes = {
      noOfBlocks:"",
      flatHierarchy:false,
      drivePlus:false
    };
  }
saveP1PlantInfoPromptMetadataHandler(){
    console.log(' prompt specific att -> '+ JSON.stringify(this.coreAttributes));
  }
}

HTML

<template for:each={coreAttributes} for:item="coreAttribute">
              <tr key={coreAttribute.key}>
                <th>{coreAttribute.attributeHeader}</th>
                <td>
                  <template if:false={coreAttribute.isPicklist}>
                    <input type={coreAttribute.attributeDataType} name={coreAttribute.attributeHeader}
                     value={coreAttribute.attributeValue}/>
                  </template>
                  <template if:true={coreAttribute.isPicklist}>
                    <select size="1" name={coreAttribute.attributeHeader}>
                      <option value="None">--None--</option>
                      <template for:each={coreAttribute.picklistValues} for:item="attributePickValues">
                        <option key={coreAttribute.key} value={coreAttribute.attributeValue}>{attributePickValues}</option>
                      </template>
                    </select>
                  </template>
                </td>
              </tr>
<lightning-button
        class="slds-m-left_small"
        variant="brand"
        label="Save"
        title="Save"
        onclick={saveP1PlantInfoPromptMetadataHandler}
      ></lightning-button>
            </template>

Apex class

public with sharing class P1PlantInfoPromptSolar {

    @AuraEnabled(cacheable=true)
        public static String queryCoreAttributes() {
            List<Core_Attribute__c> coreAttributesList = new List<Core_Attribute__c>();
            Map<Id,Set<String>> picklistValuesToPicklistMasterMap = new Map<Id,Set<String>>();

            coreAttributesList = [SELECT Id, Name, Data_Type__c, Type__c, Picklist_Master__c 
                FROM Core_Attribute__c WHERE Base_Asset_Name__c IN (SELECT Id FROM Base_Asset_Template__c WHERE Name = 'Base PV Plant') 
                ORDER BY Name ASC];

            picklistValuesToPicklistMasterMap = Utils.getPicklistValues(); 

            System.debug(' picklistValuesToPicklistMasterMap '+ picklistValuesToPicklistMasterMap);

            List<coreAttributesWrapper> coreAttributesWrapperList = new List<coreAttributesWrapper>();
            for(Core_Attribute__c coreAttribute : coreAttributesList){
                coreAttributesWrapper coreAttWrapper = new coreAttributesWrapper();
                coreAttWrapper.attributeHeader = coreAttribute.Name;
                coreAttWrapper.attributeDataType = coreAttribute.Data_Type__c.toLowerCase();
                coreAttWrapper.picklistValues = (coreAttribute.Data_Type__c == 'Picklist') ? picklistValuesToPicklistMasterMap.get(coreAttribute.Picklist_Master__c): null;
                coreAttWrapper.isPicklist = (coreAttribute.Data_Type__c == 'Picklist');
                coreAttWrapper.attributeValue = '';
                coreAttributesWrapperList.add(coreAttWrapper);
            }
            System.debug(' core Att '+ coreAttributesWrapperList);
            return JSON.serialize(coreAttributesWrapperList);
        }

        public class coreAttributesWrapper{
            public String attributeHeader;
            public String attributeDataType;
            public Set<String> picklistValues;
            public boolean isPicklist;
            public String attributeValue;
        }
    }

1 Answer 1

3

"Reactive" simply means that a change made by JavaScript will trigger a corresponding update in the UI. The inverse is not also true. You must somehow acquire/track the changes, usually via a change handler or by checking the values in the fields.

Example:

<input onchange={changeValueHandler} data-key={coreAttribute.key} type={coreAttribute.attributeDataType} name={coreAttribute.attributeHeader}

...

changeValueHandler(event) {
  this.coreAttributes
    .find(attr=>attr.key===event.target.dataset.key)
    .attributeValue = event.target.value;
}

...

<select onchange={selectValueHandler} data-key={coreAttribute.key} size="1" name={coreAttribute.attributeHeader}>

...

selectValueHandler(event) {
  const targetAttr = this.coreAttributes.find(attr=>attr.key===event.dataset.key);
    targetAttr.attributeValue = targetAttr.picklistValues[event.target.selectedIndex];
}

P.S. Your option tag is also setting the wrong value, you'll need to fix that.

1
  • Thank you so much for your reply. I got your point. Also, I'd like you to please have a look at this post related to this query but the below one is little different. It would be great if you could please please please look at it and share your inputs. stackoverflow.com/questions/62081474/…
    – Saravana
    May 29, 2020 at 9:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .