You need to sign in to do that
Don't have an account?
sukanta Anbu 7
Getting 'Cannot read property 'getElement' of undefined' in my jscript
I have a lightning component for drag and drop functionality which should invoke a post callout in apex class and the file should get saved in a external DB . However when i try to upload a file, I am getting the fllowing error.
Action failed: c:Classfileupload$controller$handleFilesChange [Cannot read property 'getElement' of undefined]
Failing descriptor: {c:Classfileupload$controller$handleFilesChange}
The following is my component
<aura:component controller="Classfileupload" implements="force:appHostable,lightning:availableForFlowScreens,force:hasRecordId,force:lightningQuickAction" access="global">
<!-- 'parentId' Aura Attribute for store the Id for Parent Record where we are attach our file -->
<aura:attribute name="recordId" type="String"/>
<!-- 'showLoadingSpinner' attribute for show/hide the uploading image and msg in aura:if-->
<aura:attribute name="showLoadingSpinner" type="boolean" default="false" />
<!-- 'fileName' attribute for display the selected file name -->
<aura:attribute name="fileName" type="String" default="No File Selected.." />
<!-- Lightning Input with file type and on file change call the 'handleFilesChange' controller -->
<aura:attribute name="jobID" type="String"/>
<!-- fetches the jobID from the record -->
<lightning:input aura:id="fileId" onchange="{!c.handleFilesChange}" type="file" name="file" label="Upload Attachment" multiple="false"/>
<div class="slds-text-body_small slds-text-color_error">{!v.fileName} </div>
<!--use aura:if for show-hide the loading spinner image-->
<aura:if isTrue="{!v.showLoadingSpinner}">
<div class="slds-text-body_small slds-text-color_error">Uploading...
<img src="/auraFW/resources/aura/images/spinner.gif" class="spinner-img" alt="Loading"/>'
</div>
</aura:if>
<br/>
<lightning:button aura:id="submit" type="button" class="submit" onclick="{!c.doSave}">Upload Attachment</lightning:button>
</aura:component>
The following is my .js file
({
doSave: function(component, event, helper) {
var fileInput = component.find("file").getElement();
var file = fileInput.files[0];
console.log('file is coming==>'+file);
var reader = new FileReader();
reader.onload = function (e) {
var fileContent = reader.result;
var base64 = 'base64,';
var dataStart = fileContent.indexOf(base64) + base64.length;
fileContent = fileContent.substring(dataStart)
console.log(fileContent);
var jobID = component.get("v.jobID");
var recordId = component.get("v.recordId");
var action = component.get("c.POST");
action.setParams({ file : fileContent, jobID : jobID });
action.setCallback(this, function(response) {
var returnValue = response.getReturnValue();
console.log('returnValue===>'+returnValue);
component.set("v.message", returnValue);
});
$A.enqueueAction(action);
};
reader.readAsDataURL(file);
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
mode: 'sticky',
message: 'Success',
messageTemplate: '{0} record created! See it {1}!',
messageTemplateData: ['Job', {
url: 'https://csv-file-upload.herokuapp.com/leads/' + jobID,
label: 'here',
}
]
});
toastEvent.fire();
},
handleFilesChange: function(component, event, helper) {
var input = component.find("file").getElement();
input.handleFilesChange();
var action = component.get("c.createJob");
action.setCallback(this, function(response) {
var returnValue = response.getReturnValue();
console.log(returnValue);
component.set("v.recordId", returnValue[0]);
component.set("v.jobID", returnValue[1]);
});
$A.enqueueAction(action);
window.setTimeout(
$A.getCallback(function() {
$A.util.removeClass(component.find('previewContainer'),"slds-hide");
}), 5000
)
},
})
The following is my apex class
public with sharing class Classfileupload {
@AuraEnabled
public static List<String> createJob() {
List<String> myList = new List<String>();
DMS__c dms = new DMS__c(Name='Amtex Demo3',Description__c='Test',Folder__c='Active',Key_Words__c='Test');
insert dms;
Id recordId = dms.Id;
DMS__c recdms = [SELECT id, JobID__c, id_reference__c FROM DMS__c WHERE id = :recordId];
update recdms;
myList.add(recordId);
myList.add(recdms.JobID__c);
system.debug('ID LIST: ' + myList);
return myList;
}
@AuraEnabled
public static String POST(Blob file, String jobID, String fileName) {
Http h = new Http();
String url = 'https://csv-file-upload.herokuapp.com/leads/' + jobID;
String separationString = 'da5cbc76-39ba-4f80-8b81-090b82e90cf0';
String str = file.toString();
// String csvBody = EncodingUtil.base64Encode(csvBlob);
// decode
Blob decodedBlob = EncodingUtil.base64Decode(str);
system.debug('string ==>'+decodedBlob);
// convert to string
String result = decodedBlob.toString();
// assemble the body payload
String header = '--' + separationString + '\nContent-Disposition: form-data; name="file"; filename="' + fileName + '"\nContent-Type: application/octet-stream\n\n';
//String body = EncodingUtil.base64Encode(file) + '\n';
String body = result + '\n';
String footer = '--' + separationString + '--';
String bodyPayload = header + body + footer;
system.debug('PAYLOAD: ' + bodyPayload);
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type', 'multipart/form-data; boundary=' + separationString);
req.setEndpoint(url);
req.setMethod('POST');
req.setBody(bodyPayload);
system.debug('REQUEST: ' + req);
// Send the request, and return a response
HttpResponse res = h.send(req);
System.debug(res.getBody());
return res.getBody();
}
}
Help me figure out what mistake is in this code and how to successfully get the file saved in external DB
Action failed: c:Classfileupload$controller$handleFilesChange [Cannot read property 'getElement' of undefined]
Failing descriptor: {c:Classfileupload$controller$handleFilesChange}
The following is my component
<aura:component controller="Classfileupload" implements="force:appHostable,lightning:availableForFlowScreens,force:hasRecordId,force:lightningQuickAction" access="global">
<!-- 'parentId' Aura Attribute for store the Id for Parent Record where we are attach our file -->
<aura:attribute name="recordId" type="String"/>
<!-- 'showLoadingSpinner' attribute for show/hide the uploading image and msg in aura:if-->
<aura:attribute name="showLoadingSpinner" type="boolean" default="false" />
<!-- 'fileName' attribute for display the selected file name -->
<aura:attribute name="fileName" type="String" default="No File Selected.." />
<!-- Lightning Input with file type and on file change call the 'handleFilesChange' controller -->
<aura:attribute name="jobID" type="String"/>
<!-- fetches the jobID from the record -->
<lightning:input aura:id="fileId" onchange="{!c.handleFilesChange}" type="file" name="file" label="Upload Attachment" multiple="false"/>
<div class="slds-text-body_small slds-text-color_error">{!v.fileName} </div>
<!--use aura:if for show-hide the loading spinner image-->
<aura:if isTrue="{!v.showLoadingSpinner}">
<div class="slds-text-body_small slds-text-color_error">Uploading...
<img src="/auraFW/resources/aura/images/spinner.gif" class="spinner-img" alt="Loading"/>'
</div>
</aura:if>
<br/>
<lightning:button aura:id="submit" type="button" class="submit" onclick="{!c.doSave}">Upload Attachment</lightning:button>
</aura:component>
The following is my .js file
({
doSave: function(component, event, helper) {
var fileInput = component.find("file").getElement();
var file = fileInput.files[0];
console.log('file is coming==>'+file);
var reader = new FileReader();
reader.onload = function (e) {
var fileContent = reader.result;
var base64 = 'base64,';
var dataStart = fileContent.indexOf(base64) + base64.length;
fileContent = fileContent.substring(dataStart)
console.log(fileContent);
var jobID = component.get("v.jobID");
var recordId = component.get("v.recordId");
var action = component.get("c.POST");
action.setParams({ file : fileContent, jobID : jobID });
action.setCallback(this, function(response) {
var returnValue = response.getReturnValue();
console.log('returnValue===>'+returnValue);
component.set("v.message", returnValue);
});
$A.enqueueAction(action);
};
reader.readAsDataURL(file);
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
mode: 'sticky',
message: 'Success',
messageTemplate: '{0} record created! See it {1}!',
messageTemplateData: ['Job', {
url: 'https://csv-file-upload.herokuapp.com/leads/' + jobID,
label: 'here',
}
]
});
toastEvent.fire();
},
handleFilesChange: function(component, event, helper) {
var input = component.find("file").getElement();
input.handleFilesChange();
var action = component.get("c.createJob");
action.setCallback(this, function(response) {
var returnValue = response.getReturnValue();
console.log(returnValue);
component.set("v.recordId", returnValue[0]);
component.set("v.jobID", returnValue[1]);
});
$A.enqueueAction(action);
window.setTimeout(
$A.getCallback(function() {
$A.util.removeClass(component.find('previewContainer'),"slds-hide");
}), 5000
)
},
})
The following is my apex class
public with sharing class Classfileupload {
@AuraEnabled
public static List<String> createJob() {
List<String> myList = new List<String>();
DMS__c dms = new DMS__c(Name='Amtex Demo3',Description__c='Test',Folder__c='Active',Key_Words__c='Test');
insert dms;
Id recordId = dms.Id;
DMS__c recdms = [SELECT id, JobID__c, id_reference__c FROM DMS__c WHERE id = :recordId];
update recdms;
myList.add(recordId);
myList.add(recdms.JobID__c);
system.debug('ID LIST: ' + myList);
return myList;
}
@AuraEnabled
public static String POST(Blob file, String jobID, String fileName) {
Http h = new Http();
String url = 'https://csv-file-upload.herokuapp.com/leads/' + jobID;
String separationString = 'da5cbc76-39ba-4f80-8b81-090b82e90cf0';
String str = file.toString();
// String csvBody = EncodingUtil.base64Encode(csvBlob);
// decode
Blob decodedBlob = EncodingUtil.base64Decode(str);
system.debug('string ==>'+decodedBlob);
// convert to string
String result = decodedBlob.toString();
// assemble the body payload
String header = '--' + separationString + '\nContent-Disposition: form-data; name="file"; filename="' + fileName + '"\nContent-Type: application/octet-stream\n\n';
//String body = EncodingUtil.base64Encode(file) + '\n';
String body = result + '\n';
String footer = '--' + separationString + '--';
String bodyPayload = header + body + footer;
system.debug('PAYLOAD: ' + bodyPayload);
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type', 'multipart/form-data; boundary=' + separationString);
req.setEndpoint(url);
req.setMethod('POST');
req.setBody(bodyPayload);
system.debug('REQUEST: ' + req);
// Send the request, and return a response
HttpResponse res = h.send(req);
System.debug(res.getBody());
return res.getBody();
}
}
Help me figure out what mistake is in this code and how to successfully get the file saved in external DB
({
MAX_FILE_SIZE: 4500000, //Max file size 4.5 MB
CHUNK_SIZE: 750000, //Chunk Max size 750Kb
uploadHelper: function(component, event) {
// get the selected files using aura:id [return array of files]
var fileInput = component.find("fuploader").get("v.files");
// get the first file using array index[0]
var file = fileInput[0];
var self = this;
// check the selected file size, if select file size greter then MAX_FILE_SIZE,
// then show a alert msg to user,hide the loading spinner and return from function
if (file.size > self.MAX_FILE_SIZE) {
component.set("v.fileName", 'Alert : File size cannot exceed ' + self.MAX_FILE_SIZE + ' bytes.\n' + ' Selected file size: ' + file.size);
return;
}
// create a FileReader object
var objFileReader = new FileReader();
// set onload function of FileReader object
objFileReader.onload = $A.getCallback(function() {
var fileContent = objFileReader.result;
var base64 = 'base64,';
var dataStart = fileContent.indexOf(base64) + base64.length;
fileContent = fileContent.substring(dataStart);
// call the uploadProcess method
self.uploadProcess(component, file, fileContent);
});
objFileReader.readAsDataURL(file);
},
uploadProcess: function(component, file, fileContent) {
// set a default size or startpostiton as 0
var startPosition = 0;
// calculate the end size or endPostion using Math.min() function which is return the min. value
var endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
// start with the initial chunk, and set the attachId(last parameter)is null in begin
this.uploadInChunk(component, file, fileContent, startPosition, endPosition, '');
},
uploadInChunk: function(component, file, fileContent, startPosition, endPosition, attachId) {
// call the apex method 'SaveFile'
var getchunk = fileContent.substring(startPosition, endPosition);
var action = component.get("c.SaveFile");
action.setParams({
recordId: component.get("v.recordId"),
fileName: file.name,
contentType: file.type,
file: fileContent
});
// set call back
action.setCallback(this, function(response) {
// store the response / Attachment Id
returnValue = response.getReturnValue();
var state = response.getState();
if (state === "SUCCESS") {
// update the start position with end postion
startPosition = endPosition;
endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
// check if the start postion is still less then end postion
// then call again 'uploadInChunk' method ,
// else, diaply alert msg and hide the loading spinner
if (startPosition < endPosition) {
this.uploadInChunk(component, file, fileContent, startPosition, endPosition, returnValue);
} else {
alert('File has been uploaded successfully');
}
// handel the response errors
} else if (state === "INCOMPLETE") {
alert("From server: " + response.getReturnValue());
} else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " + errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
// enqueue the action
$A.enqueueAction(action);
}
})
Now the file is getting sent via the POST callout without getting saved in the Salesforce standard object
All Answers
It seems you are trying to get the file from the input below:
<lightning:input aura:id="fileId" onchange="{!c.handleFilesChange}" type="file" name="file" label="Upload Attachment" multiple="false"/>
In that case, the aura:id should be used, The code would be like this:
var fileInput = component.find("fileId").getElement();
I want to get the input file. So i have change the code as following.
<input aura:id="file" type="file" name="file"></input>
But still I am getting the following error:
[NoErrorObjectAvailable] Script error.
newErrorHandler()@https://static.lightning.force.com/ap16/auraFW/javascript/ozbOZt5SYUotl8he3imvcA/aura_proddebug.js:50227:14
errorHandlerWrapper()@https://static.lightning.force.com/ap16/auraFW/javascript/ozbOZt5SYUotl8he3imvcA/aura_proddebug.js:50243:25
K.dispatchEvent()@https://static.lightning.force.com/ap16/auraFW/javascript/ozbOZt5SYUotl8he3imvcA/aura_proddebug.js:8666:28
K.dispatchChangeEventWithDetail()@https://sukanta02-dev-ed.lightning.force.com/components/lightning/input.js:2:29721
K.dispatchChangeEvent()@https://sukanta02-dev-ed.lightning.force.com/components/lightning/input.js:2:32750
K.handleChange()@https://sukanta02-dev-ed.lightning.force.com/components/lightning/input.js:2:31512
http://hellosnl.blogspot.com/2017/08/lightning-component-for-attaching-files.html
The major change points are:
1. add this in html:
<aura:attribute name="fileToBeUploaded" type="Object[]"/>
2. Change: <input aura:id="file" type="file" name="file" files="{!v.fileToBeUploaded}"></input>
3. follow method onFileUploaded:function in js controller and upload in helper
4. follow Apex method FileUploadController
thanks a ton for your help. I will try the above coding. The requirement is that I donot want the file to be saved in sfdc. I just have to pass the file immediately when uploaded to the POST callout to be saved in external database. That is the reason I have not added the 'uploadFile' method in the 'FileUploadController'. Can you suggest for this scenario? Thanks in advance.
({
MAX_FILE_SIZE: 4500000, //Max file size 4.5 MB
CHUNK_SIZE: 750000, //Chunk Max size 750Kb
uploadHelper: function(component, event) {
// get the selected files using aura:id [return array of files]
var fileInput = component.find("fuploader").get("v.files");
// get the first file using array index[0]
var file = fileInput[0];
var self = this;
// check the selected file size, if select file size greter then MAX_FILE_SIZE,
// then show a alert msg to user,hide the loading spinner and return from function
if (file.size > self.MAX_FILE_SIZE) {
component.set("v.fileName", 'Alert : File size cannot exceed ' + self.MAX_FILE_SIZE + ' bytes.\n' + ' Selected file size: ' + file.size);
return;
}
// create a FileReader object
var objFileReader = new FileReader();
// set onload function of FileReader object
objFileReader.onload = $A.getCallback(function() {
var fileContent = objFileReader.result;
var base64 = 'base64,';
var dataStart = fileContent.indexOf(base64) + base64.length;
fileContent = fileContent.substring(dataStart);
// call the uploadProcess method
self.uploadProcess(component, file, fileContent);
});
objFileReader.readAsDataURL(file);
},
uploadProcess: function(component, file, fileContent) {
// set a default size or startpostiton as 0
var startPosition = 0;
// calculate the end size or endPostion using Math.min() function which is return the min. value
var endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
// start with the initial chunk, and set the attachId(last parameter)is null in begin
this.uploadInChunk(component, file, fileContent, startPosition, endPosition, '');
},
uploadInChunk: function(component, file, fileContent, startPosition, endPosition, attachId) {
// call the apex method 'SaveFile'
var getchunk = fileContent.substring(startPosition, endPosition);
var action = component.get("c.SaveFile");
action.setParams({
recordId: component.get("v.recordId"),
fileName: file.name,
contentType: file.type,
file: fileContent
});
// set call back
action.setCallback(this, function(response) {
// store the response / Attachment Id
returnValue = response.getReturnValue();
var state = response.getState();
if (state === "SUCCESS") {
// update the start position with end postion
startPosition = endPosition;
endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
// check if the start postion is still less then end postion
// then call again 'uploadInChunk' method ,
// else, diaply alert msg and hide the loading spinner
if (startPosition < endPosition) {
this.uploadInChunk(component, file, fileContent, startPosition, endPosition, returnValue);
} else {
alert('File has been uploaded successfully');
}
// handel the response errors
} else if (state === "INCOMPLETE") {
alert("From server: " + response.getReturnValue());
} else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " + errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
// enqueue the action
$A.enqueueAction(action);
}
})
Now the file is getting sent via the POST callout without getting saved in the Salesforce standard object