0

When creating a screen flow using LWC, how do we pass a custom object into the flow, update the custom object, then pass the updated object back to the flow? No child components used here, just one component designed to update the object.

When passing my custom object to the flow, I understand that you must use a FlowAttributeChangeEvent to push changes back to the flow for updates in subsequent screens. I've successfully used this method with primitive variables, but I can't seem to make this work with an object.

To get any variables set in previous screens to show in the page, or to bind a change to a variable in the JavaScript, I had to clone the object passed in from the flow, and use that variable to bind the data in the markup.

When proceeding to the next screen in the flow, the custom object is not reflecting any changes.

Here's an example of the code I'm currently using:

lwcInFlow.html

<template>
 <lightning-input type="checkbox" label="Field 1" value={clonedCustomObject.field1__c} onchange={handleChangeCustomObject} name="input1"></lightning-input>
</template>

lwcInFlow.js

import { LightningElement, api} from 'lwc';
import { FlowAttributeChangeEvent} from 'lightning/flowSupport';
export default class customObjectScreenName extends LightningElement {

@api customObject;
@api clonedCustomObject;
connectedCallback() {
        this.clonedCustomObject = {...this.customObject};
    }
handleChangeCustomObject(event) {
        this.clonedCustomObject.field1__c = event.target.checked;
        console.log('JSON: ' + JSON.stringify(clonedCustomObject)); //outputs JSON: {"Field1__c":true}
        const attributeChangeEvent = new FlowAttributeChangeEvent('customObject', this.clonedCustomObject);
        this.dispatchEvent(attributeChangeEvent);
    }
}

lwcInFlow.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>47.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__FlowScreen</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen">
            <property name="customObject" type="@salesforce/schema/CustomObject__c" label="customObject"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

This method works just fine when using Aura components, but I'm thinking there is something I'm missing here that is specific to LWC.

Any ideas on how to achieve this would be greatly appreciated.


UPDATE: Okay, so for anybody that comes across this post, here is what I ended up doing. The issue was that I was trying to use the value property to toggle the checkbox on off. LWC's use the checked property to toggle the box on or off, and to bind to your variable. I also modified my change handler to work with all the input fields, rather than have a handler for every field. Code below.

lwcInFlow.html

<template>
 <lightning-input type="checkbox" name="Field_1__c" label="Field 1" checked={clonedCustomObject.field1__c} onchange={handleChangeCustomObject}></lightning-input>
<lightning-input type="checkbox" name="Field_2__c" label="Field 2" checked={clonedCustomObject.field2__c} onchange={handleChangeCustomObject}></lightning-input>
</template>

lwcInFlow.js

import { LightningElement, api} from 'lwc';
import { FlowAttributeChangeEvent} from 'lightning/flowSupport';
export default class customObjectScreenName extends LightningElement {

@api customObject;
@api clonedCustomObject;
connectedCallback() {
        this.clonedCustomObject = {...this.customObject};
    }
handleChangeCustomObject(event) {
        const name = event.target.name;
        switch(name){
            case "Field_1__c": this.clonedCustomObject.Field_1__c = event.target.checked;
            break;
            case "Field_2__c": this.clonedCustomObject.Field_2__c = event.target.checked;
            break;
        }
        const attributeChangeEvent = new FlowAttributeChangeEvent('customObject', 
        this.clonedCustomObject);
        this.dispatchEvent(attributeChangeEvent);
    }
}
0

The value property is not relevant for the Lightning-Input field, you need to look at the "checked" property on it. This has caught me out before!

| improve this answer | |
1

enter image description here

Have you made the flow variable available for input and output?

| improve this answer | |
  • Hi Andrew, yes the variable is set to input and output. – MattZ Mar 31 at 15:02
0

Turns out that the value was being updated and passed to the next screen, however, I've uncovered some interesting behavior with the checkbox/toggle version of lightning-input. It seems that even though the variable's field value is carried over, the component does not see the 'true' value that was input on the previous screen, even though its value property is set to the field, and instead defaults to false, despite a template isTrue={} ensuring that the view state is up to date with the objects data. Other fields that aren't boolean values render fine.

As per the description above, this code works. Note that the value property is now redundant, as the view state is now rendering the checkbox either checked or unchecked based on the variable's value that is passed from the flow.

<template>
  <template if:true={clonedCustomObject.field1__c}>
     <lightning-input type="checkbox" label="field1" value={clonedCustomObject.field1__c}
                      onchange={handleChangeCustomObject} name="input1" checked> 
     </lightning-input>
  </template>
  <template if:false={clonedCustomObject.field1__c}>
     <lightning-input type="checkbox" label="field1" value={clonedCustomObject.field1__c}
                      onchange={handleChangeCustomObject} name="input1" unchecked> 
     </lightning-input>
  </template>
<template>

This does not work. The '{clonedCustomObject.TextField__c}' does render outside of the template isTrue={clonedCustomObject}, and the value of clonedCustomObject.field1__c IS true in this scenario.

<template>
{clonedCustomObject.TextField__c}
   <template isTrue={clonedCustomObject}>
     <lightning-input type="checkbox" label="Field 1" value={clonedCustomObject.field1__c} 
      onchange={handleChangeCustomObject} name="input1"></lightning-input>
   </template
</template>

This leads me to believe that the value property of lightning-input, at least when used as a checkbox, is not functioning as it should be when used in a flow screen.

If anybody could shed some more light on this behavior, it would be much appreciated.

| improve this answer | |
  • The behavior you're seeing is explained at length here: unofficialsf.com/… TLDR: Flow has to decide in certain screen transition scenarios whether to treat the input to a lightning component as a default (only gets used the first time) or a 'true' input that resets every time. In Summer '20, all Next transitions will do a 'reset' that factors in any previous screen activity. – Alex Edelstein Apr 2 at 5:23
  • @Alex Thanks for the link! – MattZ Apr 3 at 11:28

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.