2

There's a strange behavior when analyzing result of an apex method compared to actual data received in LWC.

A LWC component (added on a Lightning record page) is calling an Apex method via @wire function where the return type of the apex method is a Map<String,Object>. It seems that when the map property's value is null, wire service is ignoring them in the result.

The objective of the LWC component is to display the apex data in a table with mass edit feature, such that we can edit existing values and complete null fields, this is why null field values are also important.

All components are saved with API version 50.

Here's a just simple example illustrating the issue and including results obtained from logs:

Apex controller

public with sharing class ContactServerController {

    @AuraEnabled(cacheable=true)
    public static Map<String,Object> getContactList(String accId) {
        
        Map<String,Object> result = new Map<String,Object>();
        List<Map<String,Object>> listMContacts = new List<Map<String,Object>>();

        for(Contact con : [SELECT Id, FirstName, LastName,MobilePhone, Phone
            FROM Contact
            WHERE AccountId = :accId and MobilePhone = null
            LIMIT 5]){
            
            Map<String,Object> mapContacts = new Map<String,Object>();
            mapContacts.put('Id',con.Id);
            mapContacts.put('FirstName',con.FirstName);
            mapContacts.put('LastName',con.LastName);
            mapContacts.put('MobilePhone',con.MobilePhone);
            mapContacts.put('Phone',con.Phone);
            listMContacts.add(mapContacts);
        }
        
        result.put('records',listMContacts);
        system.debug(LoggingLevel.DEBUG, '###Data result = '+ result);

        return result;
    }
}

Debug logs

###Data result = {records=({FirstName=Jack, Id=003B000000H65ZFIAZ, LastName=Rogers, MobilePhone=null, Phone=(555) 000-0000}, 
{FirstName=Jane, Id=003B000000I2tm2IAB, LastName=Doe, MobilePhone=null, Phone=null})}

LWC JS Controller

import { LightningElement, api, wire, track } from 'lwc';
import fetchContactList from '@salesforce/apex/ContactServerController.getContactList';

export default class SampleFindContacts extends LightningElement {
    @track recordData = [];
    @api recordId ='';
    @track wiredsObjectData;

    @wire(fetchContactList, { accId: '$recordId'})
    wiredSobjects(result) {
        this.wiredsObjectData = result;
        if (result.data) {
            this.recordData = result.data.records;
            console.log(JSON.stringify(this.recordData));

        }
    }
}

Console log

[{"Id":"003B000000H65ZFIAZ","FirstName":"Jack","LastName":"Rogers","Phone":"(555) 000-0000"},
{"Id":"003B000000I2tm2IAB","FirstName":"Jane","LastName":"Doe"}]

Notice the result of apex debug logs, we can see that MobilePhone and Phone properties have null values.

But when comparing with logs from LWC JS function, these 2 properties are not returned at all received. Why are the null properties missing ?

Has anyone encountered such issue ?

6
  • 1
    Why are you asking this? Is this causing some sort of problem? – sfdcfox Oct 31 '20 at 19:49
  • all the map properties are useful info whether null or not. from the LWC, the values can be edited and sent back to apex. When the property value is null and hence missing in LWC, cannot manipulate the array of objects to edit its values – Shamina Nov 1 '20 at 5:09
  • If updating records using updateRecord, data should be passed to apex in RecordInput format and you can specify values for any missing field. On the other hand, if you use custom apex method, you can pass the missing field data in your own custom format. Regardless, good catch. – arut Nov 1 '20 at 10:50
  • getRecord gets the null fields, but doesn't help in case of retrieving list or map of Sobject. I wonder if this could also be due to some apex side optimization while handing over the data to lightning, but couldn't find any official SF documentation in this regard. – arut Nov 1 '20 at 10:55
  • 1
    @arut Thanks, getRecord wont fit for this use case, we need the map structure and update is done via custom apex method. I've used such map structure before with LWC and we did receive null property values, not sure when this stopped working. Logged a case with SF support – Shamina Nov 3 '20 at 8:06
1

If you would like to keep it consistent, probably try to send map as a String and then Parse it in LWC

##Apex Changes :

return JSON.serialize(result);

##LWC Changes :

this.recordData = JSON.parse(result.data).records;

With Current Code -> APEX is probably not sending the null to JS (As JS is not receiving the null params), it can be because of LDS optimization -

(https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.data_ui_api)

Lightning Data Service does a lot of work to make code perform well.

  • Optimizes server calls by bulkifying and deduping requests.
1
  • Thanks for this, I ended finding a workaround indeed to capture the null fields. See answer posted, SF support provided different documentation and informed that this is working as designed, there's also an idea still active on this topic – Shamina Dec 30 '20 at 10:22
0

SF support informed that this is working as designed and can be applied for both Aura and LWC.

Here is the compiled response the senior team provided to the Salesforce Technical Support:

Given the info provided, the repro performed and the outcome of testing, this issue is working as designed: when an SObject is returned by an @AuraEnabled controller action, any fields on the SObject that have null values are not passed to JavaScript through action.getReturnValue().

This has been WAD ever since Winter'15 as per : https://trailblazer.salesforce.com/ideaView?id=08730000000Dh1MAAS

I also believe this may be down to the Wire TypeScripting occurring as per: https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_decorators https://www.typescriptlang.org/docs/handbook/advanced-types.html#nullable-types

I think this can be worked around by doing input checks during the mapping function to forcibly populate with a string of the user's choosing, including a string of NULL if needed.

For reference case #28127653

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.