2

I am trying to import a library into Salesforce Lightning using ltng:require. Problem is, when I try to use some of the objects from the library in my controller, it can't find those objects. I have a static resource called "adaptivecardsjs" which contains the publicly distributed Javascript file for the Adaptive Cards library, and another resource called "adaptivecardscss," which just contains an empty css for now. Here's my .cmp:

<aura:component>
    <ltng:require scripts="{!$Resource.adaptivecardsjs + '/adaptivecards.js'}" styles="{!$Resource.adaptivecardscss + '/adaptivecards.css'}"
        afterScriptsLoaded="{!c.jsLoaded}"/>
    <div>
        {!v.body}
    </div>
</aura:component>

And my controller .js file:

    ({
        jsLoaded: function(component, event, helper) {
        var card = {
            "type": "AdaptiveCard",
            "version": "1.0",
            "body": [
                {
                    "type": "Image",
                    "url": "http://adaptivecards.io/content/adaptive-card-50.png"
                },
                {
                    "type": "TextBlock",
                    "text": "Hello **Adaptive Cards!**"
                }
            ],
            "actions": [
                {
                    "type": "Action.OpenUrl",
                    "title": "Learn more",
                    "url": "http://adaptivecards.io"
                },
                {
                    "type": "Action.OpenUrl",
                    "title": "GitHub",
                    "url": "http://github.com/Microsoft/AdaptiveCards"
                }
            ]
        };
        var adaptiveCard = new AdaptiveCards.AdaptiveCard();
        adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
            fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
            // More host config options
        });

        // Set the adaptive card's event handlers. onExecuteAction is invoked
        // whenever an action is clicked in the card
        adaptiveCard.onExecuteAction = function(action) { alert("Ow!"); }

        // For markdown support you need a third-party library
        // E.g., to use markdown-it, include in your HTML page:
        //     <script type="text/javascript" src="https://unpkg.com/markdown-it/dist/markdown-it.js"></script>
        // And add this code to replace the default markdown handler:
        //     AdaptiveCards.processMarkdown = function(text) { return markdownit().render(text); }

        // Parse the card payload
        adaptiveCard.parse(card);

        // Render the card to an HTML element:
        var renderedCard = adaptiveCard.render();

        var body = component.get("v.body");
        body.push(renderedCard);
        component.set("v.body", body);
    }
})

So basically, what I want to do is take the samplefrom the website for Adaptive Cards, and render that into a lightning component. The problem though is that in the Javascript, it's not finding the AdaptiveCards. part of var adaptiveCard = new AdaptiveCards.AdaptiveCard();, which should work as long as it ran the the Javascript library shouldn't it?

2
  • is the library compatible with locker service? what kind of errors are you getting? it might be that you wont be able to use the library at all if it is not locker service compliant – glls Aug 8 '18 at 23:06
  • As far as I can tell, it is compatible, as it doesn't access DOM elements outside the component, and doesn't visit any websites. The error I'm getting is on the new AdaptiveCards.AdaptiveCard(); line, it says that I can't access the AdaptiveCard member on a null object (meaning AdaptiveCards was not actually declared). The thing is, the .js file I'm ltng:requireing literally starts with var AdaptiveCards = ..., so AdaptiveCards should be declared, shouldn't it? Or am I misunderstanding how ltng:require works? – AlexKven Aug 8 '18 at 23:37
4

There are couple of issues with this one .

  1. Webpack bundler uses a Module pattern and only way ltng:require works is by attaching the variable to the Locker secure window .

Hence I manipulated the file https://unpkg.com/adaptivecards@1.0.0/dist/adaptivecards.js with one single lines as shown below

window.AdaptiveCards = (function(modules) { // webpackBootstrap  
  1. Also when you push something to the v.body it has to be facet meaning an attribute of type aura:component .

Note you can always use plain old Javascript in Lightning components and no harm around that .

The working code is as shown below

<aura:component >
   <ltng:require scripts="{!$Resource.adaptivecardsjs}"
    afterScriptsLoaded="{!c.jsLoaded}"/>
   <div aura:id="adaptiveCard">

   </div>
 </aura:component>

The controller JS code

({
    jsLoaded: function(component, event, helper) {
    var card = {
        "type": "AdaptiveCard",
        "version": "1.0",
        "body": [
            {
                "type": "Image",
                "url": "http://adaptivecards.io/content/adaptive-card-50.png"
            },
            {
                "type": "TextBlock",
                "text": "Hello **Adaptive Cards!**"
            }
        ],
        "actions": [
            {
                "type": "Action.OpenUrl",
                "title": "Learn more",
                "url": "http://adaptivecards.io"
            },
            {
                "type": "Action.OpenUrl",
                "title": "GitHub",
                "url": "http://github.com/Microsoft/AdaptiveCards"
            }
        ]
    };
    var adaptiveCard = new AdaptiveCards.AdaptiveCard();
    adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
        fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
        // More host config options
    });

    // Set the adaptive card's event handlers. onExecuteAction is invoked
     // whenever an action is clicked in the card
     adaptiveCard.onExecuteAction = function(action) { alert("Ow!"); }

     // For markdown support you need a third-party library
     // E.g., to use markdown-it, include in your HTML page:
     //     <script type="text/javascript" src="https://unpkg.com/markdown-it/dist/markdown-it.js"></script>
    // And add this code to replace the default markdown handler:
    //     AdaptiveCards.processMarkdown = function(text) { return markdownit().render(text); }

    // Parse the card payload
    adaptiveCard.parse(card);

    // Render the card to an HTML element:
    var renderedCard = adaptiveCard.render();

     var div = component.find("adaptiveCard");
     div.getElement().appendChild(renderedCard);
   }
})

enter image description here

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.