function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ananya DhimanAnanya Dhiman 

Update fields on a custom object when user clicks on button

Hi developers, I am new to LWC and facing a little problem in acheiving my goal. I have a custom object named Livehealth__c and a web component. Whenever the user clicks on 'No' button, I want to update the following fields on my object : TotalPoints__c (type = number) and No__c (type = checkbox). 
Scenario is : I want to change No__c  = true when NO button is pressed and if it is true then I want to set TotalPoints__c  = 0 and want to the similar funcationality on 3 more components.

Here is my code : 

APEX : 
public class live {
    @AuraEnabled(Cacheable=true)
    public static List<Livehealth__c> liveheal(Boolean str){
        string jj = UserInfo.getUserId();
        system.debug('id' + jj);
        
        List<Livehealth__c> listobj = [Select Id, Name, UserId__c, Female__c, Male__c, No__c, Yes__c, Above40__c, Under40__c, TotalPoints__c from Livehealth__c
                                       where Yes__c =: str];
        system.debug('listofobject' + listobj);
        return listobj;       
    }
}

LWC : 
<template>
    <div if:true={dosomething}>
    <div class="slds-wrap">
        <div id="questions" class="c-questions">
            <div class="c-steps">
                <h1 class="c-steps__eyebrow" data-loc="questions-eyebrow"><b>Prediabetes risk assessment</b></h1>
                <div class="c-steps__wrap">
                    <div aria-hidden="true" class="current"> 
                    </div>  
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                    <div aria-hidden="true" class="">
                    </div>
                </div> 
                <div class="c-steps__line"></div> 
                <ul class="c-steps__titles slds-p-top_x-small slds-p-bottom_medium">
                    <li class="ccurrent">
                        <span>Diabetes</span>
                    </li>
                    <li class="age">
                        <span>Age</span>
                    </li>
                    <li class="age">
                        <span>Sex</span>
                    </li>
                    <li class="age">
                        <span>Family <br/> History</span>
                    </li>
                    <li class="age">
                        <span>BMI</span>
                    </li>
                    <li class="age">
                        <span>Ethnicity</span>
                    </li>
                    <li class="age">
                        <span>Blood <br/> Pressue</span>
                    </li>
                    <li class="age">
                        <span>Lifestyle</span>
                    </li>
                    <li class="age">
                        <span>Blood <br/> Test</span>
                    </li>
                </ul>
            </div>
        </div>
        
        <div class="slds-col slds-large-size_12-of      12" style="background:white; margin-top: -5rem;">
            <h2 class="head">Do you have diabetes (either type 1 or type 2)?</h2>
            <div class="twobuttons slds-grid slds-wrap"> 
                <button type="yes" class="one-button slds-button slds-button_neutral" tabindex="0" onclick={pressme}>Yes</button> &nbsp;&nbsp;&nbsp;&nbsp;
                <button type="no" class="two-button slds-button slds-button_neutral" onclick={press}>No</button>   
            </div>
        </div>
    </div>
    </div>
    <div if:true={show}>
        <c-lwc-y-e-s-s></c-lwc-y-e-s-s>
    </div>
    
    <div if:true={no}>
        <c-lwc-n-o></c-lwc-n-o>
    </div>
    
</template>

JS : 
import { LightningElement , track , wire } from 'lwc';
import liveheal from '@salesforce/apex/live.liveheal';
export default class LwcPATH extends LightningElement {
    @track listdata;
    @track error;
    @track abc = false;
    @wire(liveheal , {str : '$abc'})
    result({data , error}){
      // debugger;
        if(data){
            this.listdata = data;
            this.error = undefined;
            console.log('listdata', this.listdata);
        }
        else if(error){
            console.log('error');
            this.error = error;
            this.listdata = undefined;
        }
        console.log('error--',error);
        console.log('initial list', this.listdata);
    }
    @track dosomething = true;
    @track show = false;
    @track no = false;
    @track integer;
    pressme(){
        this.show = true;
        this.dosomething = false;
     }
     press(event){   
        debugger; 
        this.no =  true;
        this.dosomething = false;
        console.log('listdata---',this.listdata);
        if(this.listdata.No__c == false){
            this.listdata.No__c = true;
        }
        this.integer = 0;
        if(this.listdata.No__c == true){
            this.listdata.TotalPoints__c = 0;
        }
    }
}

Thanks in advance.
Ananya
Danish HodaDanish Hoda
Hi Ananya,
Please refer below points, these might help:
  • You have returned a list of Livehealth__c object
  • Initialise listdata as @track listdata = [];
  • On "No" button click, you are setting  this.listdata.No__c = true; rather you should iterate over the list and update the value.
  • Once updated, you also need to send it to Apex to save the same in database.
Ananya DhimanAnanya Dhiman
hi @danish, how do i send back this updated data to apex in lwc ???
Danish HodaDanish Hoda
//Add below line in the import section 
import saveData from '@salesforce/apex/<ClassName>.saveData';

if(this.listdata.No__c == true){
            this.listdata.TotalPoints__c = 0;
            var dataToApex = JSON.stringify(this.listdata);
             saveData({"data"  : dataToApex})
             .then(result => {
                    console.log(result);
             })
             .catch(error => {
                 console.log(error);
              });
        }

//Apex:
@AuraEnabled
public static void saveData(String data){
   List<Livehealth__c> lvs = (List<Livehealth__c>) JSON.deserailize(data, List<Livehealth__c>.class);
   UPDATE lvs;
}

 
Ananya DhimanAnanya Dhiman
Thank you so much for this help @danish but I have few things in my mind like will this above piece of code work when I try to update the vlaues on backend on click of either buttons "YES" or "NO" and I have to do this for every component that is created for this task (around 10-12 components)? Will I be using only one update method in apex fort all of these or I have to create different methods for different components?
Ananya DhimanAnanya Dhiman
@danish I also don't want to send data to my apex for every component (not on click of every button in every component i.e. there should only be one DML operation in the end) instead I want to send it back to apex in the end all at once which will have all the values of all those components on which I will performing these logics and then update my object in the end.
Danish HodaDanish Hoda
Hi Ananya,You can have just one method.
Ananya DhimanAnanya Dhiman
Hi @Danish, I am trying to do my task with the help of your code but in my apex it says that LIST is unexpected token and that line with JSON has an error that expression cannot be assigned. Why is it like this?
 
Danish HodaDanish Hoda
Hi Ananya,
please make below changes and try,
@track listdata = [];
@wire(liveheal , {str : '$abc'})
    result({data , error}){
      // debugger;
        if(data){
            listdata = [];
            //this.listdata = data;
            //this.error = undefined;
            for(var i=0; i<data.length; i++){
                 listdata.push(data[i]);
            }
            this.listdata = listdata;
            console.log('listdata', this.listdata);
        }
        else if(error){
            console.log('error');
            this.error = error;
            this.listdata = undefined;
        }
        console.log('error--',error);
        console.log('initial list', this.listdata);
    }

 
Ananya DhimanAnanya Dhiman
Hi Danish, I am not to able deploy my code because of the error "Unable to find Apex action method referenced as 'live.saveData'" 
Ananya DhimanAnanya Dhiman
This is my updated code :
/* APEX */
public class live {
    @AuraEnabled(Cacheable=true)
    public static List<Livehealth__c> liveheal(Boolean bool){
        
        List<Contact> conlist = [Select Id, Name from Contact];
        system.debug('conlist---' + conlist);
        
        List<Id> contactidlist = new List<Id>();
        for(Contact c : conlist){
            contactidlist.add(c.Id);
        }
        system.debug('contactidlist---' + contactidlist);
        
        List<Livehealth__c> listobj = [Select Id,ContactId__c,Name,Yes1__c,No1__c,Yes2__c,No2__c,Female__c,Male__c,No__c,Yes__c,Above40__c,Under40__c,TotalPoints__c 
                                       from Livehealth__c
                                       where ContactId__c =: contactidlist and No__c =: bool];
        system.debug('listofobject' + listobj);
        return listobj;       
    }
    
    @AuraEnabled(Cacheable=true)
        public static void saveData (String data){
            List<Livehealth__c> lvs = (List<Livehealth__c>) JSON.deserailize(newdata, List<Livehealth__c>.live);
            update lvs;
            system.debug('values-updated--' + lvs);
        }
}

/* JS */
import { LightningElement , track , wire } from 'lwc';
import liveheal from '@salesforce/apex/live.liveheal';
import saveData from '@salesforce/apex/live.saveData';
export default class LwcPATH extends LightningElement {
    @track listdata = [];
    @track error;
    @track abc = false;
   
    @wire(liveheal, { bool : '$abc'})
    result({data , error}){
        if(data){
            listdata = [];
           // this.listdata = data;
           // this.error = undefined;
           for (var i=0; i<data.lenght; i++){
                  listdata.push(data[i]);
           }
           this.listdata = listdata;
            console.log('listdata', this.listdata);
        }
        else if(error){
            console.log('error');
            this.error = error;
            this.listdata = undefined;
        }
        console.log('error--',error);
        console.log('initial list--',this.listdata);
    } 
    @track dosomething = true;
    @track show = false;
    @track no = false;
    @track integer;
    pressme(){
        this.show = true;
        this.dosomething = false;
     }
    press(){   
        this.no =  true;
        this.dosomething = false;
        
        if(this.listdata.No__c == false){
            console.log('NO field value', this.listdata.No__c);
            this.listdata.No__c = true;
            var dataToApex = JSON.stringify(this.listdata);
             saveData({"data"  : dataToApex})
             .then(result => {
                    console.log(result);
             })
             .catch(error => {
                 console.log(error);
              });
        }
      /*  this.integer = 0;
        if(this.listdata.No__c == true){
            this.listdata.TotalPoints__c = 0;
            console.log('points added or not---', this.listdata.TotalPoints__c);
        }*/
    }
}
Ananya DhimanAnanya Dhiman
Updated line from APEX ----
List<Livehealth__c> lvs = (List<Livehealth__c>) JSON.deserailize(data, List<Livehealth__c>.live);
Danish HodaDanish Hoda
Hi Ananya,Do not annotate cacheable=true when you are hqving DML operations