0

I have implemented the custom datatable component(the child component c-custom-table not shown in this post) that is dispatching the event once the record have been successfully saved.

parentComponent.html

<template>
    <div class="slds-p-var-around_medium">
        <lightning-card title="Some Title">
            <template if:true={someData.data}>
                <c-custom-table some-data={someData.data}
                    onrecordupdate={handleSuccess}>
                </c-custom-table>        
            </template>
        </lightning-card>
    </div>
</template>

The component is placed in the parent component that is handling the data fetching/ manipulation and passes it down to child components

parentComponent.js

import { LightningElement, api, wire } from "lwc";
import getSomeData from "c/someSobjectModule";
import { refreshApex } from "@salesforce/apex";

export default class ParentComponent extends LightningElement {
  @api recordId;

 
  @wire(getSomeData, { id: "$recordId" })
  someData;
  
  handleSuccess(event) {
    return refreshApex(this.someData);
  }
}

The problem is that the apex method is imported in a ES6 module that is handling other imports related to specific Sobject for code maintainability and also as a middle layer between front-end and back-end code.

someSobjectModule.js

import _getData from "@salesforce/apex/ApexController.getData";

const getData = (someId) => {
  return _getData({ id: someId });
};


export { getData };

The apex method is flagged as cacheable once it's only fetching the data

ApexController.cls

public with sharing class ApexController {
    @AuraEnabled(cacheable=true)
    public static List<CustomObject__c> getData(String id){
        List<CustomObject__c> data =  new List<CustomObject__c>(); 
        try {
            data = [
                SELECT Name, Quantity  
                FROM CustomObject__c 
                WHERE RelatedObjectId__c =: id ];
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
        return data;
    }
}

It seems that the wire service is not provisioning the data from apex due to inappropriate form as I am receiving the following error once I am trying to access a parent component

Message: adapter is not a constructor

Component Descriptor: c:parentComponent

If I call the apex method imperatively it behaves the same. On the other hand, if I import the apex method directly in parent component it works as expected. Is it possible to wire a method from ES6 module in parentComponent and then use refreshApex to reload the data? Am I forced exporting the apex method directly in the parent component by some framework vulnerabilities?

1 Answer 1

3

You can't use wire with this design, because there's some "background magic" that goes on with imported methods, and that magic is lost when you:

return _getData({id:someId})

This is an imperative call, not a wire call. You'd have to:

return _getData;

At which point, you're basically just adding an extra layer to what's already a fairly simple process.

But, to get around to the main question, you should technically be able to do this by building a local cache of the responses.

import _getData from "@salesforce/apex/ApexController.getData";
const cache = {};
const getData = (someId) => {
  return new Promise((resolve, reject) {
    _getData({ id: someId }).then((result) => {
      cache[someId] = result;
      resolve(result);
    });
  });
};
const refresh = (someId) => {
  return new Promise((resolve,reject) => {
    refreshApex(cache[someId]).then((result) => {
      cache[someId] = result;
      resolve(result);
    });
  });
};

export { getData, refresh };

Which you can then use as you'd expect:

getData(someId).then(...);

And:

refresh(someId).then(...);

No wire calls will work, though, because you have to use a special Apex method, which basically defeats the purpose of using wire methods to begin with.

1
  • Thanks for clarification @sfdcfox. The proposed solution is handy but it will add the unnecessary complexity so, I end up with adding the apex import in parent component Commented Apr 22, 2021 at 10:15

You must log in to answer this question.

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