2

Looking for a conditional rendering solution in lwc, which uses the initial value of a field in the database to decide whether to render or not. I have found a way to get it working, but it seems like a clumsy way of doing it. Therefore I was wondering whether there would be a better solution available. I am just learning the platform, so perhaps I am just missing something obvious.

This solution works, but seems a sub-optimal pattern to me, given for reference and to check whether it is actually the only way of doing it:

@track selectedValue;
error;

//Get the current value in the object
@wire(getRecord, { recordId: '$recordId', fields: someFields})
getSomeValue({ error, data }) {
   if (data) {
      this.selectedValue = getFieldValue(data, SOME_FIELD) === 'a certain picklist value';
      this.error = undefined;
   } else if (error) {
      this.error = error;
      this.selectedValue = undefined;
   }
}

//Show a template section conditionally
handleChangeOfSomething(event) {
    this.selectedValue = (event.target.value === 'a certain picklist value');
}

Based on the documentation on the Salesforce website for lwc I would think the suggested way to solve this would be with a getter/setter, something along the lines of this (but I am well aware that I could be completely mistaken on this of course and am not clinging on to it, it is merely here to fully state my train of thoughts):

@track selectedValue;

@wire(getRecord, { recordId: '$recordId', fields: someFields})
getSomeValue;

get isSomeValue() {
        return getFieldValue(this.getSomeValue.data, SOME_FIELD) === 'a certain picklist value';
}

set isSomeValue(newValue) {
        this.selectedValue = newValue;
}

handleChangeOfSomething(event) {
    this.selectedValue = (event.target.value === 'a certain picklist value');
}

However, this is rerendering only upon saving and therefore will not be reactive.

Questions: 1. is the second solution indeed more in the direction of the design philosophy of lwc, and should it therefore be amended in some way to become reactive? 2. is the second solution worthless and is there another way to solve this? 3. or else: is the first working solution actually the way to do this?

(IMHO it would be good to add something like this to the lwc cookbook anyway, at the moment it only gives an example without a database connection, while in real life you would want that in many cases)

  • This is a X-Y Problem. Can you tell your actual requirement initially and then explain what you attempted? You are mentioning only what you attempted but you didnt say what are you trying to solve – salesforce-sas Aug 24 '19 at 13:12
  • Dear @salesforce-sas, while I understand why you analyze my question as such, I would hold that my question does not have the form 'does X solve Y'. It rather formally has the form of A solves Y, B does not solve Y, is there any X different from A to solve Y or is there possibly a B' to solve Y. Anyway I edited the question to make it more explicit and give some context. Nevertheless thanks for looking into it of course! – Rut ger Aug 24 '19 at 17:19
  • I actually did not understand what you said in above comment. However, explained few things from what I understood from your code snippets. Hope it solves your issue. – salesforce-sas Aug 24 '19 at 21:12
  • 1
    Nevermind, it was an attempt at mild irony. But thanks a lot for your answer, this is a much better way of doing it and it makes a lot of sense. Just not the first thing that would come to my mind. Thanks a lot again! – Rut ger Aug 24 '19 at 23:28
1

As you are using handleChangeOfSomething I will take a guess that you are loading record in template and on change of one of its fields, you want to render some other part of form conditionally.

In this case the best option to use in template is lightning data services based component - most probably record-edit-form.

So, after using lightning data services in template, and again using getRecord service in javascript, you are introducing complexity in component logic. You can extract everything you want from lightning data services from onload event and there is no need of getRecord service implementation. While using onload event, we have to manually take care of how we are implementing logic as this event fires multiple times.

Also, you are correct that getter is a better option. However, the way you are implementing getter is not correct in this scenario. Getters are mainly used to automatically fetch some value in template.

Below is the sample code:

HTML:

<template>
    <div> isTypeProspect - {isTypeProspect} </div>
    <lightning-record-edit-form record-id={recordId}
                                object-api-name="Account"
                                onload={handleLoad}>
        <lightning-messages>
        </lightning-messages>
        <lightning-input-field field-name="Type" onchange={handleTypeChange}>
        </lightning-input-field>
    </lightning-record-edit-form>
</template>

JS:

@api recordId;
@track selectedType;

handleLoad(event) {
    if (!this.initDone) {
        this.selectedType = event.detail.records[this.recordId].fields.Type.value;
        this.initDone = true;
    }
}

get isTypeProspect() {
    return this.selectedType === 'Prospect';
}

handleTypeChange(event) {
    this.selectedType = event.target.value;
}
| improve this answer | |

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.