Utility Files in Lightning Web Components

In Lightning Web Components (LWC) development, creating utility files is beneficial for maintaining clean, modular code. These files carry common functionalities like displaying toast messages, logging errors, or any other utility functions enhancing user experience.

When working on Lightning Web Components (LWC) in Salesforce, maintaining a clean and modular code structure is essential for better readability, reusability, and maintainability. One effective way to achieve this is by utilizing utility files to house commonly used functions and methods.

Advertisements

The Need for Utility Files

In the course of LWC development, you often encounter scenarios where certain functionalities are common across multiple components. These may include displaying toast messages, logging errors, or other utility functions that enhance the overall user experience. Instead of duplicating code in each component, consider creating a dedicated utility file.

Here’s an example of how your project structure should look:

force-app
└───main
    └───default
        └───lwc
            ├───myLWCComponent
            |   ├── myLWCComponent.html
            |   ├── myLWCComponent.js
            |   └── myLWCComponent.css
            └── utility.js

Creating a Utility File

Suppose you frequently need to display toast messages and log errors in your components at different location and functions. You can create a utility file named utility.js:


import { ShowToastEvent } from 'lightning/platformShowToastEvent'

let mainObj;

export default class Utility {


    constructor(superMain) {
        mainObj = superMain;
    }

    //show toast message on the UI
    showToast(title, variant, message){
        const toastEvent = new ShowToastEvent({
            title: title,
            variant: variant,
            message: message,
        });
        mainObj.dispatchEvent(toastEvent);
    }

    //log error into logger framework
    logError(error) {
        //log error in browser console
        console.log(error);

        //log error in nebula framework
        const logger = mainObj.template.querySelector('c-logger');  
        logger.error(JSON.stringify(error));
        logger.saveLog();    
    }

    // Method to format date in MM/DD/YYYY format
    formatDate(dateTimeString) {
        // If dateTimeString is null, undefined, or an empty string, return an empty string
        if (!dateTimeString) {
            return '';
        }
        const dateTime = new Date(dateTimeString);
        const month = dateTime.getMonth() + 1;
        const day = dateTime.getDate();
        const year = dateTime.getFullYear();

        console.log(`${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`);
        
        return `${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`;
    }

}

1. Constructor and Initialization

The utility class begins with a constructor that takes a superMain parameter, representing the main context or instance of the LWC component where the utility class is instantiated. This establishes a connection between the utility class and the component, facilitating interaction with the component’s properties and methods.

constructor(superMain) {
    mainObj = superMain;
}

2. Show Toast Message Method

The showToast method enables the display of toast messages on the UI. It takes three parameters: title (the title of the toast), variant (the visual style of the toast – success, error, etc.), and message (the content of the toast). This method utilizes the Lightning Web Components ShowToastEvent to trigger the display of the toast.

showToast(title, variant, message) {
    const toastEvent = new ShowToastEvent({
        title: title,
        variant: variant,
        message: message,
    });
    mainObj.dispatchEvent(toastEvent);
}

3. Logging Error Method

The logError method serves a dual purpose: it logs the error in the browser console and, additionally, it logs the error in a custom logging framework (referred to as “nebula framework” in the example). The utility class assumes the existence of a logger component with the tag c-logger in the main component. The error is first logged in the console using console.log(error), and then it’s logged into the nebula framework using the logger component.

logError(error) {
    // Log error in browser console
    console.log(error);

    // Log error in nebula framework
    const logger = mainObj.template.querySelector('c-logger');  
    logger.error(JSON.stringify(error));
    logger.saveLog();    
}

4. Date Formatting Method

The formatDate method takes a date-time string as input and returns a formatted date in the “MM/DD/YYYY” format. It checks for null, undefined, or empty string values and returns an empty string in such cases. The formatted date is then logged to the console before being returned.

formatDate(dateTimeString) {
    // If dateTimeString is null, undefined, or an empty string, return an empty string
    if (!dateTimeString) {
        return '';
    }

    // Convert dateTimeString to a JavaScript Date object
    const dateTime = new Date(dateTimeString);

    // Extract month, day, and year components
    const month = dateTime.getMonth() + 1;
    const day = dateTime.getDate();
    const year = dateTime.getFullYear();

    // Log the formatted date to the console
    console.log(`${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`);
    
    // Return the formatted date
    return `${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`;
}

Incorporating this utility class into your LWC components can streamline common operations, promote code reuse, and contribute to the overall maintainability of your Salesforce applications. Feel free to adapt and extend these utility methods based on your specific project requirements.

Integrating Utility Methods

Now, let’s see how you can seamlessly integrate these utility methods into your LWC components. Consider a component named myLWCComponent.js:

import { LightningElement } from 'lwc';
import Utils from './utility';
let utility;
export default class MyLWCComponent extends LightningElement {

    connectedCallback(){

        utility = new Utils(this);
        this.myFun1();
        this.myFun2();
        this.myFun3();
    }
    
    //call util functions from different methods in this file.

    myFun1(){
        let currentdate = new Date(); 
        let followingDay = new Date(currentdate.getTime() + 86400000); // + 1 day in ms

        utility.formatDate(followingDay);
        utility.showToast('Error Message','error','This error generated from component');
    }

    myFun2(){
        
        try{
            //Any exception that occurs here will be caught in the catch block and sent to a utility method for logging.

        }catch(error){
            utility.logError(error);
        }
    }

    myFun3(){
        let currentdate = new Date(); 
        utility.formatDate(currentdate);
    }

   
}
Advertisements

Benefits of Using Utility Files

1. Modularity

By organizing related functions in a dedicated file, your code becomes modular and easier to understand. Each utility file can focus on a specific set of functionalities.

2. Reusability

Utility methods can be reused across multiple components, promoting a DRY (Don’t Repeat Yourself) coding philosophy. This not only saves development time but also ensures consistency.

3. Separation of Concerns

Utility files help separate business logic from the component’s rendering logic. This clear separation makes it easier to maintain and update your codebase.

4. Readability

Descriptive names for utility files and methods enhance the overall readability of your code. Developers can quickly grasp the purpose of each utility method.

5. Ease of Testing

Isolating utility methods makes them easier to test independently. This contributes to improved testability and overall code quality.

Best Practices

  • Keep it Focused: Each utility file should have a specific focus, containing related utility methods.
  • Use Descriptive Names: Name your utility file and methods descriptively to convey their purpose.
  • Export Only What’s Necessary: Only export the functions or variables that are intended to be used outside the utility file.
  • Version Control: Include utility files in version control along with your LWC components for better traceability.

Conclusion

Incorporating utility files into your Lightning Web Components development workflow can significantly enhance your code organization and efficiency. The ability to encapsulate common functionalities in a modular way ensures that your components remain clean, maintainable, and scalable.

By following best practices such as keeping utility files focused, using descriptive names, and exporting only what’s necessary, you pave the way for a streamlined development process. Consider adopting this approach in your Salesforce projects, and experience the power of well-organized LWC code.

About the blog

SFDCLessons is a blog where you can find various Salesforce tutorials and tips that we have written to help beginners and experienced developers alike. we also share my experience and knowledge on Salesforce best practices, troubleshooting, and optimization. Don’t forget to follow us on:

Newsletter

Subscribe to our email newsletter to be notified when a new post is published.

Advertisements
Advertisements
Arun Kumar
Arun Kumar

Arun Kumar is a Salesforce Certified Platform Developer I with over 7+ years of experience working on the Salesforce platform. He specializes in developing custom applications, integrations, and reports to help customers streamline their business processes. Arun is passionate about helping businesses leverage the power of Salesforce to achieve their goals.

Articles: 162

2 Comments

Leave a Reply

Discover more from SFDC Lessons

Subscribe now to keep reading and get access to the full archive.

Continue reading

Discover more from SFDC Lessons

Subscribe now to keep reading and get access to the full archive.

Continue reading