0

I am writing a LWC to replace the Case Close screen which is not available in Lightning if Case Tracking is on.

In the lightning-record-edit-form the user sets the Case Status field. Some of the Status fields are not Closed statuses. Since it doesn't appear possible to remove the values from the picklist, we want to trap this situation after they submit to warn them that they went to the Case Close screen but haven't actually closed the Case.

I am trying to do this with the IsClosed field on the Case. However I am finding that because IsClosed is a read-only property, it is challenging to get the updated value upon transaction success.

import { LightningElement, api, wire, track } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';

import IS_CLOSED from '@salesforce/schema/Case.IsClosed';
import RECORDTYPEID from '@salesforce/schema/Case.RecordTypeId';
const FIELDS = [IS_CLOSED,RECORDTYPEID];

export default class LwcCloseCaseForm extends LightningElement {
    @api recordId;
    @track recordTypeId;
    @track showSpinner;
    @track record;

    @wire(getRecord, { recordId: '$recordId', fields: FIELDS })
    fetchCase(response) {
        this.record = response;
    }

    get isClosed() {
        return getFieldValue(this.record.data, IS_CLOSED);
    }

    get recordTypeId() {
        this.recordTypeId = getFieldValue(this.record.data, RECORDTYPEID);
        return rtId;
    }

    handleSuccess(event) {

        // Just completed a transaction where the Case went to a Closed status
        console.log('handleSuccess');
        this.showSpinner=false;
        refreshApex(this.record);

        if (this.record.data.fields.IsClosed.value){
            // Show green toast
            console.log('Case is Closed');
        } else {
            // Show yellow toast
            console.log('Case is Open');
        }

        console.log(this.isClosed);

        const payload = event.detail;
        console.log('Payload: ' + JSON.stringify(payload));

}

On submit, the transaction posts normally from the LWC. The properties in the UI update fine - in the UI (if:true={isClosed} blocks are displaying). The log statements in the Success method represent the three ways I've found to get the record values, short of requerying manually with Apex. After refreshApex was called, they yield:

  1. Test 1: if/then for this.record.data.fields.IsClosed.value returns Case is Open (i.e., false)
  2. Test 2: wired property this.isClosed returns false
  3. Test 3: IsClosed is not included in the event payload since it is a read-only field

I've investigated some possibilities here but nothing is jumping out at me. I would hope it's not an asynchronous problem since this is on success. I'm wondering if refreshApex isn't firing because it doesn't detect the record has changed?

How can I get the current value of IsClosed on success?

Thanks in advance.

0

By using @wire, you create a reactive service - you delegate the invocation of getRecord to the wire service, that will provide new values every time that 1) the parameters passed with $ change or 2) the cache it's notified there's a new value.

lightning-record-edit-form notifies the cache when the record changes, so, you shouldn't need to use refreshApex (that's needed when something else changes the record on the database, as an Apex call, or an inbound API call...).

This means the wire service will provide the new value when lightning-record-edit-form changes the record, without having to use refreshApex. That moment happens(normally) after the handleSuccess() handler is executed.

I see what you're doing trying to force the refresh, but bear in mind even if that worked (refreshApex is not documented for this use case, but it may work, I haven't tested it), what refreshApex does it to tell the wire service to provide a new value - asynchronously - so, when the lines right after your refreshApex call executed, the new value wouldn't be there yet.

One solution would be to retrieve the record at that point doing a one time invocation (that way you control the invocation yourself, instead of delegating it to the wire service) - but I think that complicates things. What I suggest to do instead is to show the warning before saving the record. For instance:

Html:

<template>
  <lightning-record-edit-form
    record-id={recordId}
    object-api-name="Case"
    onsubmit={handleSubmit}
  >
    <lightning-messages> </lightning-messages>
    <lightning-input-field field-name="Status"> </lightning-input-field>

    <lightning-button
      class="slds-m-top_small"
      variant="brand"
      type="submit"
      name="update"
      label="Update"
    >
    </lightning-button>
  </lightning-record-edit-form>
</template>

Javascript:

import { LightningElement, api } from "lwc";

export default class CaseClose extends LightningElement {
  @api recordId;

  handleSubmit(event) {
    event.preventDefault(); // Stop the form from submitting
    const fields = event.detail.fields;
    if (fields.Status !== "Closed") {
      // ShowToast...
      console.log("Not closing!");
    }
    this.template.querySelector("lightning-record-edit-form").submit(fields);
  }
}

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.