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;
    }
}
  • Are you getting any error message? or do you have more info on what you exactly mean with not working? – Sven Delporte Jan 20 '17 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 Jan 20 '17 at 8:14
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
    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 – Santanu Halder Jan 20 '17 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 Jan 23 '17 at 3:27

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.