0

I have a custom LWC page where I am importing an array of JS object to CSV and it is working as expected now I need to do some changes to that csv file and upload it on the page and convert it back to an array of JS object.

I have tried to use the below code

HTML:

<lightning-file-upload name="fileUploader" accept={acceptedFormats} record-id={productconfigid}
                    onuploadfinished={handleUploadFinished}>
</lightning-file-upload>

JS:

 handleUploadFinished(event) {
        // Get the list of uploaded files
        const uploadedFiles = event.detail.files;
        console.log(uploadedFiles);
        alert("No. of files uploaded : " + uploadedFiles.length);
    }

The above doesn't work because I am using my LWC component from lighting out and as per the documentation upload file would be disabled in lightning out but in my case it is not disabled upon clicking upload files it opens a pop up to upload a file and when I select the file nothing happens, no alert no console logs.

other then above I have tried custom html element to do the same.

HTML:

<form id='importPfForm'>
         <input type='file' name='datafile' id="input">
         <input type='button' value='IMPORT' onclick={handleUploadFinished} />
   </form>

JS:

    handleUploadFinished(event) {

            const uploadedFiles = this.template.querySelector('input').files[0];
            console.log(uploadedFiles ); 
   }

console log prints below information regarding the uploaded file

File {name: "uploadedFile.csv", lastModified: 1587959237199, lastModifiedDate: Mon Apr 27 2020 09:17:17 GMT+0530 (India Standard Time), webkitRelativePath: "", size: 4995, …}

if I change my JS to below to read the data from file

handleUploadFinished() {

    this.template.querySelector('input[type="file"]')
        .addEventListener('change', function () {
            var files = this.files;

            for (var i = 0; i < files.length; i++) {
                parseCSV(files[i], ',', function (result) {
                    console.log(result);
                });
            }
        })
}

parseCSV(file, delimiter, callback) {
    var reader = new FileReader();

    // When the FileReader has loaded the file...
    reader.onload = function () {

        // Split the result to an array of lines
        var lines = this.result.split('\n');

        // Split the lines themselves by the specified
        // delimiter, such as a comma
        var result = lines.map(function (line) {
            return line.split(delimiter);
        });

        // As the FileReader reads asynchronously,
        // we can't just return the result; instead,
        // we're passing it to a callback function
        callback(result);
    }

    // Read the file content as a single string
    reader.readAsText(file);
}

upon clicking the import button nothing happens, no console log nothing, it doesn't execute code inside the addEventListner method but the above code is working as expected in this [JS Fiddle][1]

can someone please suggest why the same is not working in LWC?

UPDATE:

Code mentioned by sfdcfox is working as expected but the only problem is when when one of the row values have special character then it doesn't parse csv as expected for example

srNumber, names 1,john doe 2,Frank 3,vito 4,Tom, hagen

up to first 3 line it will work as expected but on 4th line name Tom, hagen has comma in it which creates problems while reading the content.

1

You're adding a handler to the input element to fire when a change occurs, but you've already selected the file and clicked the import button. So, it would wait until the next change before that happens. Instead, just go ahead and read the files.

Here's a simple demonstration:

import { LightningElement, track, api } from 'lwc';

export default class App extends LightningElement {
    readFiles() {
        [...this.template
            .querySelector('input[type="file"]')
            .files].forEach(async file => {
                try {
                    const result = await this.load(file);
                    // Process the CSV here
                    console.log(result);
                } catch(e) {
                    // handle file load exception
                }
            });
    }
    async load(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = function() {
                resolve(reader.result);
            };
            reader.onerror = function() {
                reject(reader.error);
            };
            reader.readAsText(file);
        });
    }
}

<template>
    <input type="file" multiple accept=".csv"/>
    <button onclick={readFiles}>Import</button>
</template>
| improve this answer | |
  • Thank you Brain for your kind help would you please suggest how to ignore special characters when reading the csv file? – gs650x Apr 28 at 10:32
  • Maybe have a look at PapaParse as this library contains sophisticated parsing logic for CSV files in JavaScript: papaparse.com – Christian Menzinger Apr 28 at 10:37
  • @gs650x Reading your comment, this is improper CSV format. A real CSV file will put quotes around fields that contain commas, new lines, etc. See RFC 4180. Even then, you will need to do more than just "split on comma and read". There's not too many rules in CSV, so doing it by hand isn't hard, but a parser library as mentioned above could be useful. – sfdcfox Apr 28 at 11:23
  • @ChristianMenzinger would you please be kind to post an answer on how to use third party library to do all the stuff, I have read csv and then need to convert it into array of objects – gs650x Apr 28 at 11:25
  • @sfdxfox updating my question with more details – gs650x Apr 28 at 11: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.