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;
}
| improve this question | | | | |
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.

| improve this answer | | | | |
  • you never fail to answer the tougher questions. Thank you – TemporaryFix Sep 7 '18 at 16:16
  • @Programatic You're welcome. Always glad to help when I can. – sfdcfox Sep 7 '18 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 – TemporaryFix Sep 7 '18 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 Sep 7 '18 at 16:49

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.