3

I have a lightning component that queries for a Static Resource and returns the body.

When the lightning component receives the blob data aura throws an error

This page has an error. You might just need to refresh it. Action failed: c:ProductUploader$controller$getTemplate [n.split is not a function] Failing descriptor: {c:ProductUploader$controller$getTemplate}

I am attempting to download this file to the user using some functionality listed here.

I know I can return a base64 String and convert it using the functions in that related post, but by returning the blob I can reduce about 75% of the code from that post.

Component

<aura:component controller="ProductCreationController">
    <aura:handler name="init" value="{!this}" action="{!c.getTemplate}"/>
    <lightning:layout>

        <lightning:layoutItem size="4" />

        <lightning:layoutItem size="2">
            <!-- place holder for download link -->
        </lightning:layoutItem>
        <lightning:layoutItem size="2">
            <!-- place holder for file upload button -->
        </lightning:layoutItem>

        <lightning:layoutItem size="4" />
    </lightning:layout>
</aura:component>

Controller

({
    getTemplate : function(component, event, helper) {

        var action = component.get(component.get('c.getTemplateBlobData'));
        action.setParams({});
        action.setCallback(this, function(response) {
            if (response.getState() == 'SUCCESS') {
                var templateData = response.getReturnValue();
                console.log(templateData);
            }
        });
        $A.enqueueAction(action);
    }
})

Apex

@AuraEnabled
public static Blob getTemplateBlobData() {
    return [
        SELECT Body 
        FROM StaticResource 
        WHERE Name = 'New_Product_Template'
    ].Body;
}

1 Answer 1

7

You must use base-64 encoding if you want to do it this way. The reason why is that internally, Lightning uses JSON, so passing binary data through either way may have unexpected results. If necessary, you might need to return the binary data through several round trips to the server. Alternatively, just make an XMLHttpRequest directly to "/resource/resourceName".

let xhr = new XMLHttpRequest();
xhr.open("GET", "/resource/New_Product_Template");
xhr.onload = $A.getCallback(function() {
  // do something with this.response or xhr.response
});
xhr.send(null);

This method bypasses the maximum file limit entirely.

4
  • you never fail to answer the tougher questions. Thank you Commented Sep 7, 2018 at 16:16
  • @Programatic You're welcome. Always glad to help when I can.
    – sfdcfox
    Commented Sep 7, 2018 at 16:19
  • I can actually bypass the javascript entirely by using the $Resource provider. <a href="{!$Resource.New_Product_Template}" download="New_Product_Template">Download Template</a> Not sure why I didn't think of this in the first place Commented Sep 7, 2018 at 16:46
  • 1
    @Programatic I thought you had some sort of other motive where you needed access to the file in your script, too, otherwise I would have recommended the more direct approach. You're certainly right, though, that would be best if that's all you need.
    – sfdcfox
    Commented Sep 7, 2018 at 16:49

You must log in to answer this question.

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