2

I'm still such a newbie in this programming. I tried to create a file upload in lightning and tried several examples online but still found it not working. I just don't know the problem anymore. If you may, can you help me find what's wrong? Below are my codes. I have omitted all other html elements to make it simpler. Thank you in advance to those who have a kind heart to help me understand.

COMPONENT

<form>    
    <label class="slds-form-element__label"  
             for="disabledTextInput">Placement</label>
    <c:InputLookup type="{!v.placement.sobjectType}" 
             value="{!v.newItem.Placement__c}" />            

<label class="slds-form-element__label" for="text-input-01">Item </label>
        <ui:inputText aura:id="itemname" label="" class="slds-input"
                        labelClass="slds-form-element__label"
                        value="{!v.newItem.Item__c}"/>

<label >Placement </label>
        <ui:inputText aura:id="itemplacement" label="" class="slds-input"
                        labelClass="slds-form-element__label"
                        value="{!v.newItem.Placement__c}"/>

<label>Location </label>
        <ui:inputText aura:id="itemlocation" label="" class="slds-input"
                        labelClass="slds-form-element__label"
                        value="{!v.newItem.Location__c}"/>

<label>Description </label>                 
             <ui:inputTextArea aura:id="description" label="" 
               value="{!v.newItem.Description__c}" rows="5"/>

<label >Attachment </label>   
      <input type="file" class="file" aura:id="file" 
          onchange="{!c.previewFile}"/>
      <img src="" height="100"></img>
         <ui:button label="Save" press="{!c.createNewItem}"/>                               
</form>

JS CONTROLLER

({
    createNewItem: function(component, event, helper) 
    {
       var newItem = component.get("v.newItem");       
       helper.createNewItem(component, newItem); 
        this.save();
    },
    save : function(component, event, helper) {
        helper.save(component);
    },       
    //to preview the image attached
        previewFile: function(component, event) {
        var preview = document.querySelector('img');
        var file    = document.querySelector('input[type=file]').files[0];
        var reader  = new FileReader();

        reader.addEventListener("load", function () {
            preview.src = reader.result;
        }, false);

        if (file) {
            reader.readAsDataURL(file);
        }
    }
})

JS HELPER

({
    createNewItem:function(component, newItem)
    {
        var action = component.get("c.createItem");
        console.log(newItem);
       action.setParams({"newItem" : newItem});
       action.setCallback(this,function(response){   
       var state = response.getState(); 
       if(state === "SUCCESS")
         {              alert("Saved");} 
            else if(state === "ERROR")
         {              alert("Error: not saved");   }

        console.log("Create new Item: " + newItem);
        });
        $A.enqueueAction(action)
        this.save();
    },

    MAX_FILE_SIZE: 750 000, 
    save : function(component) {
        var fileInput = component.find("file").getElement();
        var file = fileInput.files[0];

        if (file.size > this.MAX_FILE_SIZE) {
            alert('File size cannot exceed ' + this.MAX_FILE_SIZE + 
            ' bytes.\n' + 'Selected file size: ' + file.size);
            return;
        }

        var fr = new FileReader();        
        var self = this;
        fr.onload = function(){
            var fileContents = fr.result;
            var base64Mark = 'base64,';
            var dataStart = fileContents.indexOf(base64Mark)
                + base64Mark.length;
            fileContents = fileContents.substring(dataStart);       
            self.upload(component, file, fileContents);
        };
        fr.readAsDataURL(file);
    },       
    upload: function(component, file, fileContents) {
        var action = component.get("c.saveTheFile"); 
        action.setParams({
            parentId: component.get("v.parentId"),
            fileName: file.name,
            base64Data: encodeURIComponent(fileContents), 
            contentType: file.type
        });

        action.setCallback(this, function(a) {
            attachId = a.getReturnValue();
            console.log(attachId);
        });

        $A.getCallback(function() {$A.enqueueAction(action); });
    }
})

APEX CONTROLLER

public with sharing class NewInventoryItemController {   
    @AuraEnabled  
    public static Inventory_Item__c createItem (Inventory_Item__c newItem)
    {    
        insert newItem;
        system.Debug('newItem: '+newItem);
        return newItem;
    }

    @AuraEnabled
    public static Id saveTheFile(Id parentId, String fileName, 
        String base64Data, String contentType) { 
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');

        Attachment a = new Attachment();
        a.parentId = parentId;

        a.Body = EncodingUtil.base64Decode(base64Data);
        a.Name = fileName;
        a.ContentType = contentType;

        insert a;
        system.Debug('Attachment '+a);
        return a.Id;
    }
}
2
  • Are you getting any error message? or do you have more info on what you exactly mean with not working? Commented Jan 20, 2017 at 8:01
  • Hi, this is the error that I get: Action failed: c$NewInventoryItem$controller$createNewItem [Cannot read property 'find' of undefined] Failing descriptor: {c$NewInventoryItem$controller$createNewItem} ... I tried to add a value on the input tag but it doesnt work as well...
    – Mae
    Commented Jan 20, 2017 at 8:14

1 Answer 1

3

While calling save() in helper from the createNewItem() of helper, you are not passing the component as argument to the save method.

createNewItem:function(component, newItem) {
    // logics
    this.save(component) // pass the component as argument.
}

Also you need to wrap the FileReader's onload callback with $A.getCallback() inside of $A.getCallback(function() {$A.enqueueAction(action); }); which is not required if you do the former change.

Eg:

fr.onload = $A.getCallback(function(){
    //file reading logic
});
2
  • 2
    In addition to this, fr.readAsDataURL(file); won't work when LockerService is enabled in your org. Just a heads up. Its a known issue Commented Jan 20, 2017 at 18:06
  • Hi, thank you for responding. I've already passed the component but I got another error. Action failed: c$NewInventoryItem$controller$save [system is not defined] Failing descriptor: {c$NewInventoryItem$controller$save}. Also, the attached image is showing on my form, so i think fr.readAsDataURL(file); is working...however when I click save it fails to insert to my salesforce fields. what might be the problem here?
    – Mae
    Commented Jan 23, 2017 at 3:27

You must log in to answer this question.

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