0

I am facing an issue with getting the latest data on a simple search and update form that i have made in LWC. All i am trying to do is to search a case, get the details and then update it. It works fine when i search for the first case.

Issue : Suppose i typed in case # 00001028 and press "Get case" it works, and without updating the reocord i think hey, that was not the right case # and then i edit the case # to 00001027 and then press "Get case" i get an error pop up saying cannot read property 'api Name' of undefined. However, once is press ok on the error, the case 00001027 is rendered on the lighting-record-form??? This is weird.. Please help.

Below is the code i am using

<template>
    <lightning-card title='Case Search and Update'>
        <div class="slds-p-around_medium lgc-bg">
            <lightning-input type="text" label="Case #" placeholder='Search for a Case..' onchange={handleCaseNumChange}></lightning-input> 
        </div>

        <template if:true={showGetCase}>
            <div class="slds-p-left_medium">
                <lightning-button variant="brand" label="Get Case" onclick={handleButtonClick} ></lightning-button>
            </div>
        </template>

        <div class="slds-p-left_medium">
        <template if:true={showForm}>

           <lightning-record-form
            record-id={recordId}
            object-api-name={objectApiName}
            fields={fields}
            columns="2"
            mode="view"
            onsubmit={handleSubmit}
            oncancel={handleCancel} 
            onsuccess={handleSuccess}
            onerror={handleError}
            onload={handleload}>
            </lightning-record-form> 
            </template>
        </div>
    </lightning-card>


</template>

JS :

import { LightningElement,track,wire,api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import findId from '@salesforce/apex/fetchCaseNumber.fetchId'
import REASON_FIELD from '@salesforce/schema/Case.Reason';
import ContactEmail_FIELD from '@salesforce/schema/Case.ContactEmail';
import AccountId_FIELD from '@salesforce/schema/Case.AccountId';
import Type_FIELD from '@salesforce/schema/Case.Type';
import Description_FIELD from '@salesforce/schema/Case.Description';
import Subject_FIELD from '@salesforce/schema/Case.Subject';
import Comments_FIELD from '@salesforce/schema/Case.Comments';
import ParentId_FIELD from '@salesforce/schema/Case.ParentId';
import Product_FIELD from '@salesforce/schema/Case.Product__c';
import IsEscalated_FIELD from '@salesforce/schema/Case.IsEscalated';
import OwnerId_FIELD from '@salesforce/schema/Case.OwnerId';
import { refreshApex } from '@salesforce/apex';

export default class SearchAndUpdateCase extends LightningElement {
    @track caseNumber;
    @track csNum;
    showForm = false;
    showGetCase = true;
    @track recordId;
    objectApiName = 'Case';
    wireddata;

    @wire(findId,{caseNum : '$csNum'})
    csId(result){
        if(result.data){
            this.wireddata = result;
            //this.recordId = result.data;
        }
        else if(result.error){
            console.log('>>>>Did not find record>>>>');
        }
    } ;

    @track fields = [REASON_FIELD,ContactEmail_FIELD,AccountId_FIELD,Description_FIELD,Type_FIELD,Subject_FIELD,
        Comments_FIELD,ParentId_FIELD,Product_FIELD,IsEscalated_FIELD,OwnerId_FIELD ];


    handleCaseNumChange(event){
        //console.log('>>Inside handle case change');
        this.csNum = event.target.value;
        //console.log('>>>The typed incident number is '+this.csNum);
        //console.log('>>>Case Id is :'+JSON.stringify(this.csId)); 
    }

    handleButtonClick(event){
        //refreshApex(this.wireddata);
        //console.log( '>>>Button click data'+this.csId.data);
        //if(this.csId){
        if(this.wireddata.data){    
            if (this.showForm===false) 
                this.showForm = true;
            //this.recordId = this.csId.data;
            this.recordId = this.wireddata.data;
            refreshApex(this.wireddata);
        }
        //this.showGetCase = false;

    }

    handleSubmit(event){
        event.preventDefault();       // stop the form from submitting
        console.log('>>>Event target>>'+event.target);
        console.log('>>>Event detail>>'+event.detail);
        console.log('>>>Event data>>'+event.data);
        console.log('>>Inside Submit<<');
        const fields = event.detail.fields;
        //fields.Comments += 'My Custom Comment'; // modify a field
        this.template.querySelector('lightning-record-form').submit(fields);

     } 

     handleSuccess(event){
        console.log('>>>Inside success<<<');
        const evt = new ShowToastEvent({
            title: "Case Updated",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(evt);
        this.showForm = false;
        //refreshApex(this.wireddata);

     }

     handleCancel(event){

        console.log('>>Inside Cancel<<');
        this.showForm = false;
     }

     handleError(event){
         console.log('>>Inside error>>');
     }

     handleload(event){

        console.log('>>>>Loaded<<<<');
        //refreshApex(this.wireddata);
     }
}

APEX:

public class fetchCaseNumber {
    @AuraEnabled(cacheable=true)
    public static string fetchId(string caseNum){
        case cs = new case();
        system.debug('>>Case Num is  >> '+caseNum);
        cs = [select Id from case where casenumber = :caseNum];
        system.debug('>>Returning >> '+cs);
        return (string)cs.Id;
    }
}

enter image description here.

7
  • can you set this.showForm = true; after this.recordId = this.wireddata.data; in your handleButtonClick method? This might fix your issue. Commented Apr 7, 2020 at 8:29
  • Tried doing that, still the same issue.. Commented Apr 7, 2020 at 9:39
  • i copied your code it worked fine for me
    – User6670
    Commented Apr 7, 2020 at 10:58
  • @User6670 : Did you try fetching one case and then without updating it, fetching another case from the input box? It's not giving you the error? Commented Apr 7, 2020 at 11:08
  • Yes I didn't got any error in both the scenarios the only thing different will be the apex class can you edit your question and add that too
    – User6670
    Commented Apr 7, 2020 at 11:12

2 Answers 2

1

What I would do in your case is set the Id to something that is going to come from the record. You are changing the Id and not changing the form out with the new Id. You should hide the form on change of the csNum, then if your return finds something, show the form with the new Id. By unrendering the form, you force the component to reinstantiate it again with your new Id.

HTML:

<lightning-record-form
    record-id={wiredData}
    object-api-name={objectApiName}
    fields={fields}
    columns="2"
    mode="view"
    onsubmit={handleSubmit}
    oncancel={handleCancel} 
    onsuccess={handleSuccess}
    onerror={handleError}
    onload={handleload} >
</lightning-record-form> 

JS:

@track wiredData;

@wire(findId,{caseNum : '$csNum'})
csId({ error, data }){
    if(data){
        this.wiredData = data !== null && data !== undefined ? data : undefined;
        this.showForm = data !== undefined;
    }
    else if(error){
        console.log('>>>>Did not find record>>>>', error );
    }
} ;


handleCaseNumChange(event){
    this.showForm = false; 
    this.csNum = event.target.value;
}

Apex:

public class fetchCaseNumber {
    @AuraEnabled(cacheable=true)
    public static Id fetchId(String caseNum){
        List<Case> results = [ SELECT Id FROM Case WHERE CaseNumber =: caseNum LIMIT 1 ];

        return results.isEmpty() ? null : results[ 0 ].Id;
    }
}
4
  • Well i guess i am almost there. The form shows up on changing the csNum without error now, but... the whole form is blank. There is not data in any of the fields now, both times the first time i enter the case number and also the time after editing... Commented Apr 7, 2020 at 15:20
  • does the actual record have data? You could check that the fields you are listing are listed properly. It should be a string array of field names. I would say that this fixes the error problem you originally inquired about. BTW - if these are lookup fields on your form, make sure that they are included in the default page layout to get them to render. If not present, they will not show the values.
    – Ronnie
    Commented Apr 7, 2020 at 18:02
  • also can you verify in your onload that the record-id attribute is set? you should be able to access it by looking at the detail attribute per the documentation: developer.salesforce.com/docs/component-library/bundle/… for event.detail.id if that is undefined, it would be problematic. you should be able to see these keys in that event detail: developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/…
    – Ronnie
    Commented Apr 7, 2020 at 18:05
  • if you see nothing in the fields attribute, try using the <field imported>.fieldApiName attribute to populate the fields array for the form instead. and likely don't need to track that array, it shouldn't be changing is wasteful to performance to track variables that aren't changing
    – Ronnie
    Commented Apr 7, 2020 at 18:09
0

I made a few edits to your answer, instead of automatically rendering the form at the wired function itself, made the showForm true only on button click. For somereason it was not working when the record-id on the form was directly wired. hmm.. weird.

Next i had another problem, where suppose i search for an existing record 'A', it will show up, and then if i search for a non-exisitng record 'B', it was still showing the old record 'A' on the form, i however over came this problem by setting the recordId to blank '' in the error function of @wire. This solved the issue.

Thanks for all the help Ronnie, you helped me solve this issue. Marking your answer as the right one.

Although i think i know why it works now and not before, maybe you can take a look at this final code (working) and let me know what was (maybe) the issue before

import { LightningElement,track,wire,api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import findId from '@salesforce/apex/fetchCaseNumber.fetchId'
import REASON_FIELD from '@salesforce/schema/Case.Reason';
import ContactEmail_FIELD from '@salesforce/schema/Case.ContactEmail';
import AccountId_FIELD from '@salesforce/schema/Case.AccountId';
import Type_FIELD from '@salesforce/schema/Case.Type';
import Description_FIELD from '@salesforce/schema/Case.Description';
import Subject_FIELD from '@salesforce/schema/Case.Subject';
import Comments_FIELD from '@salesforce/schema/Case.Comments';
import ParentId_FIELD from '@salesforce/schema/Case.ParentId';
import Product_FIELD from '@salesforce/schema/Case.Product__c';
import IsEscalated_FIELD from '@salesforce/schema/Case.IsEscalated';
import OwnerId_FIELD from '@salesforce/schema/Case.OwnerId';
import { refreshApex } from '@salesforce/apex';

export default class SearchAndUpdateCase extends LightningElement {
    @track caseNumber;
    @track csNum;
    showForm = false;
    showGetCase = true;
    @track recordId;
    objectApiName = 'Case';
    @track wireddata;

    @wire(findId,{caseNum : '$csNum'})
    csId({ error, data }){
        if(data){
            console.log('>>data>>'+data);
            this.wiredData = data !== null && data !== undefined ? data : undefined;
            this.recordId = this.wiredData;
            //this.showForm = data !== undefined;
        }
        else if(error){
            console.log('>>>>Did not find record>>>>', error );
            this.recordId = '';
        }
    } ;

    @track fields = [REASON_FIELD,ContactEmail_FIELD,AccountId_FIELD,Description_FIELD,Type_FIELD,Subject_FIELD,
        Comments_FIELD,ParentId_FIELD,Product_FIELD,IsEscalated_FIELD,OwnerId_FIELD ];


    handleCaseNumChange(event){

        this.showForm = false; 
        this.csNum = event.target.value;
        if(this.wiredData !== null && this.wiredData !== undefined)
        this.recordId = this.wiredData;

    }

    handleButtonClick(event){

            console.log('>>>RC ID >>>'+this.recordId);
            if(this.recordId)
            this.showForm = true;
        }

    handleSubmit(event){
        event.preventDefault();       // stop the form from submitting

        const fields = event.detail.fields;
        //fields.Comments += 'My Custom Comment'; // modify a field
        this.template.querySelector('lightning-record-form').submit(fields);

     } 

     handleSuccess(event){
        console.log('>>>Inside success<<<');
        const evt = new ShowToastEvent({
            title: "Case Updated",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(evt);
        this.showForm = false;
        //refreshApex(this.wireddata);

     }

     handleCancel(event){

        console.log('>>Inside Cancel<<');
        this.showForm = false;
     }

     handleError(event){
         console.log('>>Inside error>>');
     }

     handleload(event){

        console.log('>>>>Loaded<<<<');
        //refreshApex(this.wireddata);
     }
}

HTML

<template>
    <lightning-card title='Case Search and Update'>
        <div class="slds-p-around_medium lgc-bg">
            <lightning-input type="text" label="Case #" placeholder='Search for a Case..' onchange={handleCaseNumChange}></lightning-input> 
        </div>

        <template if:true={showGetCase}>
            <div class="slds-p-left_medium">
                <lightning-button variant="brand" label="Get Case" onclick={handleButtonClick} ></lightning-button>
            </div>
        </template>

        <div class="slds-p-left_medium">
        <template if:true={showForm}>

           <lightning-record-form
            record-id={recordId}
            object-api-name={objectApiName}
            fields={fields}
            columns="2"
            mode="view"
            onsubmit={handleSubmit}
            oncancel={handleCancel} 
            onsuccess={handleSuccess}
            onerror={handleError}
            onload={handleload}>
            </lightning-record-form> 
            </template>
        </div>
    </lightning-card>


</template>

You must log in to answer this question.

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