2

I am having the issue that at times when inserting a document from lightning component, the callback is not executing. At times it executes when on chrome, and at time not when on IE. I don't know why. Here is the code :

 canSaveFile : function(component, helper){
    console.log('## starting method upload image');   
  //check if profile pic uploaded
  component.set("v.errorMsg",null);

    var fileInput = component.find("file").getElement();
  var file = fileInput.files[0];
  var _validFileExtensions = ["jpg", "jpeg", "bmp", "gif", "png"]; 
  var res = file.name.split(".");
  var extension = res[res.length-1];
  var fr = new FileReader();       

  console.log("file extension:" + extension);
  var filesizeInMB = file.size/1024/1024;
  console.log("file size in mb",filesizeInMB);


  if (filesizeInMB > 1) {
      component.set("v.errorMsg",'La photo de profil ne doit pas dépasser 1mb');          
      return;
  }
  else if(_validFileExtensions.indexOf(extension) < 0){
      component.set("v.errorMsg",'Ce fichier n\'est pas une image valide');        
      return;
  }

  fr.onload = function() {
      var fileContents = fr.result;
      var base64Mark = 'base64,';
      var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;          
      fileContents = fileContents.substring(dataStart);      
      helper.uploadFile(component, file, fileContents);
  };
  fr.readAsDataURL(file);       
},  

 uploadFile: function(component, file, fileContents) {
    console.log('## starting file upload with name '+    component.get("v.recordId"));
    component.set("v.imageUploading",true);

    var action = component.get("c.saveTheFile");
    action.setParams({
        "fileName": component.get("v.recordId"),
        "base64Data": encodeURIComponent(fileContents), 
        "contentType": file.type,
        "siteId": component.get("v.recordId")
    });  
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (state === "SUCCESS") {  
            var attachId = response.getReturnValue();
            console.log("## the inserted document Id :",attachId);
            component.set("v.reloaded",component.get("v.reloaded") + 1);
        }
        else {
            console.log('## error obj : ',action.getError());
            component.set("v.errorMsg",action.getError()[0].message);
        }        
        component.set("v.imageUploading",false);           
    });

    $A.enqueueAction(action);

}

In my console, i can only debug till the line :

console.log('## starting file upload with name '+    component.get("v.recordId"));

After that it doesn't get into my action even if on my server the callback where called. But in my lightning component, it doesn't enter the else.Thus my loading message keep on going and never stop. Does anyone got the same issue?

1

1 Answer 1

2

Having said the above on debugging the callback issue, i notice another trivial thing, adhering to the aura life cycle .

fr.onload = function() {
      var fileContents = fr.result;
      var base64Mark = 'base64,';
      var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;          
      fileContents = fileContents.substring(dataStart);      
      helper.uploadFile(component, file, fileContents);
  };

fr.readAsDataURL(file);

This piece of logic is essentially outside the Aura framework lifecycle. And it could be the reason why sometimes your callbacks are not getting executed or maybe callbacks that are en-queued as part of onload function in your controller is not recognized by the aura digest cycle. So you could try wrapping the call as follows and check if it resolves the issue.

fr.onload = $A.getCallback(function() {
      var fileContents = fr.result;
      var base64Mark = 'base64,';
      var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;          
      fileContents = fileContents.substring(dataStart);      
      helper.uploadFile(component, file, fileContents);
  });

fr.readAsDataURL(file);

When you wrap your anonymous functions inside $A.getCallback(), it ensures that the logic of your code is placed in the aura frameworks call stack.

More documentation on $A.getCallback is here

If wrapping the function inside $A.getCallback does not help you kindly use salesforce lightning inspector to capture the action states and share it here for a better insight.

Links :

Salesforce Lightning Inspector

Lightning Actions and Troubleshooting

2
  • I did wrap it in the $A.getCallback() method, but nothing changed :(
    – vanessen
    Mar 31, 2017 at 13:55
  • Hmm .. in that case .. could you install the lightning inspector and check if any actions are Incomplete or Aborted or most probably running if the page is loading for a while ?
    – Sumuga
    Mar 31, 2017 at 13:57

You must log in to answer this question.

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