3

I have three LWC's called (not real names) : mainLwc, firstLwc and secondLwc.
The mainLwc has helper JS file called mainLwcHelper.js and it has one function inside it.

The problem is that I can import this function in firstLwc, but can't in secondLwc or any other lwc:

enter image description here

Here all code all of my LWC:
mainLwc.html The LWC structure

<template>
    <template if:true={showFirst}>
        <c-first-lwc></c-first-lwc>
    </template>
    <template if:true={showSecond}>
        <c-second-lwc></c-second-lwc>
    </template>
</template>

mainLwcHelper.js

const doSomething = ( recordsJSON ) => {
    try {
        let records = JSON.parse(recordsJSON);
        // some logic, not important !!
        return records;
    } catch (error) {
        console.error(error);
    }
};
export{ doSomething};

mainLwc.js

import { LightningElement } from 'lwc';
export { doSomething } from './mainLwcHelper';
export default class MainLwc extends LightningElement {
  showFirst = true;
  showSecond = false;
  // code to switch between LWC's
}

firstLwc.js import function and try to call it

import { LightningElement } from 'lwc';
import { doSomething } from 'c/mainLwc';
export default class FirstLwc extends LightningElement {
    connectedCallback(){
        try {
            console.log( doSomething ); // getting function code here
            console.log( typeof doSomething );//return `function`
            let list = doSomething( '[]'); // executes without error !!
        } catch (error) {
            console.error(error); 
        }
    }
}

secondLwc.js the same code with first, but getting error here !!

import { LightningElement } from 'lwc';
import { doSomething } from 'c/mainLwc';
export default class SecondLwc extends LightningElement {
    connectedCallback(){
        try {
            console.log( doSomething ); // getting `undefined` here 
            console.log( typeof doSomething ); // returns `undefined`
            let list = doSomething( '[]'); // getting error here !!
        } catch (error) {
            console.error(error); 
        }
    }
} 

I did try:

Have anyone already faced something similar ?

Any help will be appreciated. Thanks You.

1 Answer 1

4

Yes, this is something that can happen because of how things are bundled before being sent to the client. It is for this reason that I always recommend using a service component. Separating your shared logic into its own component increases the likelihood that your components will always load in the correct order.

utils/mainLwcHelper.js

const doSomething = ( recordsJSON ) => {
    try {
        let records = JSON.parse(recordsJSON);
        // some logic, not important !!
        return records;
    } catch (error) {
        console.error(error);
    }
};
export{ doSomething};

utils/utils.js

export * from './mainWlcHelper';

mainLwc/mainLwc.js

import { doSomething } from 'c/utils';
// ...

firstLwc/firstLwc.js

import { doSomething } from 'c/utils';
// ...

secondLwc/secondLwc.js

import { doSomething } from 'c/utils';
// ...

The bundling toolchain that builds LWCs usually "gets it right," but it can go wrong in some specific circumstances. The ordering of the imports in the root component can affect other components that are in the dependency graph.

In my work project, for example, we have one component that holds common logic for every other component in the system. This component used to start off as:

import * as utils from 'c/utils';
import * as metadata from 'c/metadata';

However, because c/utils actually depended on c/metadata, it would execute too early, when c/metadata was completely undefined up to that point. Chaos ensued.

The fix was a comment and changing the order of the imports:

// NOTE: We use these imports to force load order.
// Do not change the order of these imports.
// eslint-disable-next-line no-unused-vars
import * as metadata from 'c/metadata';
// eslint-disable-next-line no-unused-vars
import * as utils from 'c/utils';

The comment wasn't strictly necessary, but we wanted to make sure a new hire wouldn't accidentally break things in hilarious but product-threatening ways.

So, in summary, it is important that you include shared libraries as a separate component, and it is important that these libraries are imported in the correct order across all components that use them. This is especially true for top-level components, as they determine the order in which all other files will load.

1
  • Wow, It is something. I created the new Utils component and it works perfectly. Thank you. Commented Feb 17, 2023 at 16:13

You must log in to answer this question.

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