2

We can't dynamically create LWC like aura does. We can embed LWC in aura, is it possible to dynamically create LWC using $A.createcomponent within aura component?

1
  • can you updated the answer, since accepted answer is outdated now?
    – ytiq
    Apr 7, 2021 at 5:30

3 Answers 3

5

No. If you want to "dynamically" create an LWC you actually have to dynamically create an Aura component that statically wraps the LWC component.

UPDATE

As can be seen in other answers here, there are some undocumented ways to work around this without using a bespoke Aura wrapper. Use with caution; being undocumented, this could stop working at any time.

6
  • There are several additional answers that are not accepted, which show how to accomplish this. Jul 25, 2023 at 20:22
  • Seems like my answer has been superseded though using undocumented behaviour (at least I have not seen the approach officially documented anywhere).
    – Phil W
    Jul 25, 2023 at 20:45
  • I'll cheerfully withdraw it if you mention that there are alternatives in the other answers - I only downvoted because google's preview brought up your answer (Not that google ever misleads anyone w/ those info boxes or anything). Jul 26, 2023 at 12:52
  • Thanks! I have also found the events don't work quite correctly w/ those - Custom dispatched events were failing to be properly handled in the aura controller. The standard events were properly handled, though Jul 26, 2023 at 19:09
  • @HungryBeagle what was the issue with event handlers? I remember that I was able to properly handle events from dynamically created components
    – ytiq
    Jul 31, 2023 at 15:00
4

Seems we were wrong... This code worked for me. The trick was to set true 'exposed' property in js-meta.xml

LWCContainerAction.cmp

<aura:component implements="force:LightningQuickAction, force:hasRecordId">
    <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>
    {!v.body}
</aura:component>   

LWCContainerActionHelper.cmp

({
init : function(component) {
    const recordId = component.get('v.recordId');
    $A.createComponent(
        `c:lwcTest`, {recordId : recordId},
        function(lwcCmp, status, errorMessage) {
            if (status === "SUCCESS") {
                var body = component.get("v.body");
                body.push(lwcCmp);
                component.set("v.body", body);
            }
            else if (status === "INCOMPLETE") {
                console.log("No response from server or client is offline.");
            }
            else if (status === "ERROR") {
                console.error("Error: " + errorMessage);
            }
        }
      );
}
})

lwcTest.html

<template>
    test success
</template>

lwcTest.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    **<isExposed>true</isExposed>**
</LightningComponentBundle>

enter image description here

I have developed Aura Component wrapper for LWC specific for Lighting Actions. So now you can call LWC from Lighting Action with additional benefits.

Repo: https://github.com/SAItm/LWCAction

2
  • Works in my case as well, but even with isExposed=false (api version 50.0). Now I'm wondering whether it is some undocumented side effect of createComponent method or we could actually rely on this behaviour to build prod ready app.
    – wesaw
    Nov 2, 2020 at 8:33
  • For a holy calm I would suggest using with isExposed=true. Nov 3, 2020 at 9:45
1

Currently creating LWC components dynamically that has exposed:false

I pass data from LWC via Messaging Channel in format

{
    name: "",
    action:  "",
    params: {};
}

Here is part of my helper method.

{
 createComponent: function(cmp, event) {

   const eventParams = event.getParams();

   if (eventParams.action !== 'open') {
     return;
   }

   const params = Object.assign({},
     eventParams.params,
     { 'aura:id': eventParams.id }
   );


   $A.createComponent(event.getParams().name,
     params,
     $A.getCallback(function(element, status, errorMessage) {
       try {
         if (status === "SUCCESS") {
           component.set('v.currentModal', element);
           const target = cmp.find('container');

           const body = target.get('v.body');

           body.push(element);
           target.set("v.body", body);
         }
       }
     }));
 }
}

I'm using this code to generate dynamic LWC modals

7
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review
    – identigral
    Apr 6, 2021 at 15:47
  • ye, you're right I'll example with code in 1 min
    – ytiq
    Apr 6, 2021 at 15:49
  • update answer with the code
    – ytiq
    Apr 6, 2021 at 15:54
  • @identigral what to do with accepted outdated answer?
    – ytiq
    Apr 6, 2021 at 15:58
  • Downvote it and/or ask the original poster to unaccept it
    – identigral
    Apr 6, 2021 at 18:23

You must log in to answer this question.

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