0

Below is the code snippet of the VF Page:

<apex:page controller="UploadPageController">
<html>
<head>
<script type="text/javascript">
    if (window.File && window.FileReader && window.FileList && window.Blob) {
    } else {
      alert('The File APIs are not fully supported in this browser.');
    }
</script>
</head>
<body>
<input type="file" id="files" name="files[]"/>
<p id="deltest"/>
<button onClick="sendDataDelete()">Delete</button>
 <script type="text/javascript">
      var EmpArray = [];    

      function parseCSV(text, lineTerminator) {

        var lines = text.split(lineTerminator);
        for(var j = 0; j<lines.length; j++){
            EmpArray.push(lines[j]);
        }
      }
function sendDataDelete(){
         Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.UploadPageController.deleteRecords}',EmpArray, function(result,event){
            if(event.type === 'exception'){
                console.log("Exception");
                console.log(event);
            }else if(event.status){
                var y = result;
                document.getElementById("deltest").innerHTML = y;
            }else {
                console.log(event.message);
            }
      }
      );
      }
 function handleFileSelect(evt) {
        var files = evt.target.files;
        var f = files[0];
        var reader = new FileReader();
        reader.onload = (function(theFile) {
            return function(e) {
            parseCSV(e.target.result, '\n');
            };
          })(f);
          reader.readAsText(f);  
      }
      document.getElementById('files').addEventListener('change', handleFileSelect, false);
    </script>
</body>
</html>
</apex:page>

Below is the Remote Action Method snippet (in UploadPageController class) being called when clicked on "Delete" Button:

  @RemoteAction
   global static string deleteRecords(List<string> lst){

   List<Employee__c> ToBeDeleted = [Select Id, EmailAddress__c from Employee__c where Type__c='Employee' AND EmailAddress__c not in:lst];
    try{
        Database.DeleteResult[] result = Database.delete(ToBeDeleted, False);
        For(Database.DeleteResult sr:result){
            if(!sr.isSuccess()){
                For(Database.error err: sr.getErrors()){
                    system.debug('@@@@'+err.getMessage());
                }
            }
        } 
    } catch(Exception e){

    } 
    return 'Success';
} 

I've a custom object Employee__c which has a picklist type__c and a Text(80) field EmailAddress__c. I'm uploading a csv file which has only one column (no header) having a list of email addresses. Using Javascript I'm converting it to a array and then passing to the Remote Action method deleteRecords(). This is supposed to compare the Employee__c records with the List<string> derived from csv and - delete the records from the custom object whose email addresses are not present in the List.

But, ToBeDeleted List always collects all the records from the Employee__c and all the records are deleted from it. Meanwhile, if I'm running the logic of deleteRecords() in Execute anonymous by creating my own List<string> "lst" (instead deriving from csv), its works as expected.

The code to parse csv to array should be working fine because there is another remote action method (in the same class) called which performs insert operation successfully (creating records whose email addresses are in csv but not in Employee__c).

1 Answer 1

1
    reader.onload = (function(theFile) {
        return function(e) {
        parseCSV(e.target.result, '\n');
        };
      })(f);

This function is calling your anonymous function immediately, before the file's been read from the file system ((f) calls the function with one parameter). Your function should look more like this:

reader.onload = e => parseCSV(e.target.result,"\n");

Or, if you still need to support older browsers:

reader.onload = function(e) { parseCSV(e.target.result,"\n"); }

You might want to add some more error handling to make sure that at least one row was processed.


Also, you've got a number of weird things in your code; they shouldn't affect anything, but are just odd.


  function parseCSV(text, lineTerminator) {

    var lines = text.split(lineTerminator);
    for(var j = 0; j<lines.length; j++){
        EmpArray.push(lines[j]);
    }
  }

Could be written simply as:

function parseCSV(text, lineTerminator) {
  EmpArray = EmpArray.concat(text.split(lineTerminator));
}

You don't need (and should not use) the try-catch block in your Apex Code:

 @RemoteAction
   global static string deleteRecords(List<string> lst){

   List<Employee__c> ToBeDeleted = [Select Id, EmailAddress__c from Employee__c where Type__c='Employee' AND EmailAddress__c not in:lst];
        Database.DeleteResult[] result = Database.delete(ToBeDeleted, False);
        For(Database.DeleteResult sr:result){
            if(!sr.isSuccess()){
                For(Database.error err: sr.getErrors()){
                    system.debug('@@@@'+err.getMessage());
                }
            }
        } 
    return 'Success';
} 

Also, you really shouldn't return Success if there were errors. I suggest you improve your error handling.

4
  • However, problem is in ToBeDeleted list. It collects all the records from Employee__c object, ignoring second part of where clause in the SOQL- [Select Id, EmailAddress__c from Employee__c where Type__c='Employee' AND EmailAddress__c not in:lst]. For example, if in the object Employee__c we have 3 email address records - A,B,C and, in the csv we have A,B,D,E,F,G then - ToBeDeleted should have record C only. But, in our case it has A,B,C records. If I'm executing in Anonymous, it successfully shows only record C. Commented Jan 15, 2018 at 15:35
  • @Fatfox The query doesn't "ignore" filters. Your list is somehow incorrect. I suspect it might be due to how you're splitting on the newlines, or it might be extra quotes, since it's a CSV, or something. You need to do real CSV parsing, not just line splitting.
    – sfdcfox
    Commented Jan 15, 2018 at 15:44
  • Thanks for your response. I guess the splitting on the newlines and putting in the array should be working because - I'm using the same array to insert the records in Employee__c. Commented Jan 18, 2018 at 8:09
  • Thanks! The issue was with csv splitting. Extra spaces were added at the end. Splitting and then removing the spaces helped. Commented Jan 26, 2018 at 10:00

You must log in to answer this question.

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