2

I have created a LWC where I am making callout using Fetch API. Callout is working as expected when I use single JS file. Now, I want to split my logic in JS into sub JS file as we can create Multiple JS file in LWC.

LWC Component Name : testLwcComp

In TestLwcComp.js:

import { LightningElement } from "lwc";
import { fetchData } from "./fetchData"; //calling fetchData JS file
export default class TestLwcComp extends LightningElement {
    @wire(getRecord, {
        recordId: "$recordId",
        fields: [someFields]
    })
    wireInfo({ error, data }) {
        if (error) {
        } else if (data) {
            let info = fetchData();
            console.log("info:" + info);
        }
    }
}

fetchData.JS(added in same LWC testLwcComp):

let information={};
export function fetchData(){
        fetch(endpoint)
        .then(response=>response.json())
        .then(data=>{
            console.log(data)
            information= {
             a: data.a,
             b:data.b,
             c:data.c
            }
        })
        .catch(error=>console.error(error));
        return information;
    }

Now in info console log of TestLwcComp.js, I am getting value as Undefined and then fetchData.JS gets executed since it has Asynchronous callout.

To control the sequence I am trying to use async await here:

let info = async =>{
let data;
data = await fetchData();
return data;
}

but It's still not working.

Can someone please tell me how can I fetch the value in info debug logs? What I am doing wrong here?

Instead of Fetch API call, If I try to return some value(synchronous execution), I can retrieve value in info console log.

2

You need to slightly tweak your code. In the utils file, declare the function as async and await the fetch call.

export default async function fetchData(url = '', params = {}) {
    const response = await fetch(url);

    if (!response.ok) {
        throw Error(response.statusText);
    }
    return response.json();
}

and in your code, you can either use async/await or use promise-based invocation.

async makeCallout(){
    try{
        let response = await fetchData('http://www.google.com');
        console.log(response);
    } catch(e){
        // handle error
    }

    // or use a promise based invocation

    fetchData('http://www.google.com').then((data)=>{
        // do something
    }).catch((err) => {
        // handle error
    });
}

I have implemented a similar pattern in this file.

However, a small suggestion based on your code snippet - Looks like you're making a callout after the data is provisioned using a wire service. I would recommend moving the callout logic also to Apex, and use a single wire call to get both the data from Salesforce and the API as well.. Making API calls from JS exposes secrets like Auth Tokens that you may send, and also you may run into CORS issues.

9
  • Wire setting has Custom Metadata values which I have to pass before making call out such as Endpoint, Token etc. I will modify the code suggested by you and get back to you in sometime. About CORS issue, 3rd party has white listed our URL and I also added the same in CSP so currently not facing an issue. But will try to add some custom setting switch here either make Apex callout or Fetch Call. Aug 4 at 15:09
  • Given that there is a token involved, I would recommend moving the callout to Apex.. Anyone can use Developer Tools on Chrome and gain access to the token... In any case, the snippets I gave above should solve the issue you're having with async callouts. Aug 4 at 15:13
  • if I use Default keyword, then I get an error while deploying the code fetchData is not exported by fetchData.js, imported by TestLwcComp.js. If I remove default keyword from fetchData.js then I can deploy the code but it's not calling the fetchData.js file. The issue is still there :( Aug 4 at 15:48
  • Try the import this way - import fetchData from './fetchUtils'; - for default exports you don't need curly braces. If it still doesnt work, please update the question with the latest code, and I will take a look Aug 4 at 15:55
  • It worked but now getting an exception that response.json() is not a function that we are returning Aug 4 at 16:02
0

In the last code segment you posted

let info = async =>{
let data;
data = fetchData();
return data;
}

There is no await.

would this maybe help?

let info = async =>{
let data;
data = await fetchData();
return data;
}
1
  • Thanks for Pointing it out. I have updated the code. Still the issue is there Aug 4 at 15:02

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.