Site icon Salesforce Diaries

Dependency Injection & multi step in LWC

Dependency injection is used to make a class independent of its dependencies or to create a loosely coupled program. It is useful for improving the reusability of code. Creating a multi step in LWC with dependency injection using custom metadata involves designing a component where each step can be configured through metadata, results in more flexible and dynamic multi step process.

Business Usecase : Creating an application using multi step architecture in LWC using metadata powered

We’ll build a multi step application where each step’s configuration—such as component name and order—is defined through custom metadata. This approach allows us to easily update the application steps without editing the underlying code, providing flexibility and ease of maintenance.

Code: multi step in LWC

LWCConfigurationService.cls

public with sharing class LWCConfigurationService {
    @AuraEnabled(cacheable=true)
    public static List<Map<String, Object>> getConfigurations() {
        List<Map<String, Object>> configList = new List<Map<String, Object>>();
        for (Dynamic_LWC_Configuration__mdt config : [SELECT MasterLabel, Order__c, Component_Name__c 
                                                      FROM Dynamic_LWC_Configuration__mdt 
                                                      ORDER BY Order__c ASC]) 
        {
            Map<String, Object> step = new Map<String, Object>{
                'label' => config.MasterLabel,
                'order' => config.Order__c,
                'componentName' => config.Component_Name__c
            };
            configList.add(step);
        }
        return configList;
    }
}

loadAnyLwc.html

lwc:component : To instantiate a component dynamically, use the <lwc:component> managed element with the lwc:is directive in a component’s HTML file. To instantiate a component dynamically, use the <lwc:component> managed element with the lwc:is directive in a component’s HTML file.

<template>
    <div class="">
        <lwc:component lwc:is={componentConstructor}></lwc:component>
    </div>
</template>

loadAnyLwc.js

Value change handler allows to trigger the load of the new component based on component name change. To understand more on it read this: value change handler in lwc

import { LightningElement, api } from 'lwc';

export default class LoadAnyLwc extends LightningElement {
    componentConstructor;
    lwcName;

    @api get componentName() {
        return this.lwcName;
    }

    set componentName(value) {
        this.setAttribute('lwcName', value);
        this.lwcName = value;
        this.handleComponentNameChange();
    }

    handleComponentNameChange() {
        if (this.lwcName) {
            import(`c/${this.lwcName}`)
                .then(({ default: ctor }) => this.componentConstructor = ctor)
                .catch(err => console.log('Error importing component',err));
        }
    }
}

loadAnyLwc.js-meta.xml

To instantiate a dynamic component, a component’s configuration file must include the lightning__dynamicComponent capability.

<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
	<apiVersion>61.0</apiVersion>
	<isExposed>true</isExposed>
	<capabilities>
		<capability>lightning__dynamicComponent</capability>
	</capabilities>
</LightningComponentBundle>

multiPageLwc.html

loadAnyLwc component is called in html file along with back and next button. currentPage attirbute are being calculated in js file and passed to the loadAnyLwc component.

<template>    
    <template if:true={currentPage}>
        <c-load-any-lwc component-name={currentPage.componentName}></c-load-any-lwc>
    </template>
    <lightning-button label="Previous" onclick={handlePrevious}></lightning-button>
    <lightning-button label="Next" onclick={handleNext} ></lightning-button>
</template>

multiPageLwc.js

getConfigurations method from LWCConfigurationService class is called using wire service.

import { LightningElement, track, wire } from 'lwc';
import getConfigurations from '@salesforce/apex/LWCConfigurationService.getConfigurations';
export default class MultiPageLwc extends LightningElement {
    @track pages = [];
    @track currentPageIndex = 0;

    @wire(getConfigurations)
    wiredConfigs({ error, data }) {
        if (data) {
            this.pages = data;
            this.currentPageIndex = 0;
        } else if (error) {
            console.error(error);
        }
    }

    get currentPage() {
        return this.pages[this.currentPageIndex];
    }

    handlePrevious() {
        if (this.currentPageIndex > 0) {
            this.currentPageIndex--;
        }
    }

    handleNext() {
        if (this.currentPageIndex < (this.pages.length - 1)) {
            this.currentPageIndex++;
        }
    }
}

multiPageLwc.js-meta.xml

The component is exposed to use with LIghtning App Builder. You can place the component on home page, record page or app page.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>61.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Demo – Creating an application using multi-step architecture in LWC using metadata powered Depedency Injection

For testing the component, First thing we need to make sure is create metadata records. For example i have setup as shown in image below. You need to make sure component exist in your org before using them here.

Now place your component in lightning page and test:

Do you need help?

Are you stuck while working on this requirement? Do you want to get review of your solution? Now, you can book dedicated 1:1 with me on Lightning Web Component completely free.

GET IN TOUCH

Schedule a 1:1 Meeting with me

Also checkout this https://salesforcediaries.com/category/lightning-web-component

Exit mobile version