1

I used this FileReader to read csvs:

readDocument(fileChangeEvent: Event) {
  return new Observable<any>(obs => {
      const file = (fileChangeEvent.target as HTMLInputElement).files[0];
      if (file) {
        const fileReader = new FileReader();
        fileReader.onload = e => {
          obs.next({
            name: file.name,
            result: fileReader.result
          });
        };
        fileReader.readAsText(file);
      } 
    });

With this, I could then use the file in my subscription and use it's name or value anytime:

this.readDocument(csv).subscribe(value => {
            console.log(value.name);
            console.log(value.result
}

Meanwhile I have this Filereader for reading a folder that has csvs stored inside:

  public readFolder(files: string[]) {
    this.fileCache = [];
    this.readFile(0, files);
    return this.folderReader$.asObservable();
  }

  private readFile(index, files) {
    const reader = new FileReader();
    if (index >= files.length) {
      this.folderReader$.next(this.fileCache);
      return;
    }
    const file = files[index];
    const filename = file.name;
    console.log(filename);
    reader.onload = (e: any) => {
      this.fileCache.push(e.target.result);

      this.readFile(index + 1, files);
    };
    reader.readAsBinaryString(file);
  }

Now, with this i do get an array which is filled with the data of each csv in the folder. I can then later use for example a loop to show the all the file-data.

files = []
this.folderReader.readFolder(csv.target.files).subscribe(files => {
      files.forEach((value, key) => {
            console.log(key + ': ' + value);
     }
}

My problem is, id like to be able to read the value and the name of the file again, like in the first example. It should look something like this in the end:

this.folderReader.readFolder(csv.target.files).subscribe(files => {
      files.forEach((file) => {
            console.log(file.name)
            console.log(file.result)

     }
}

I am struggling to modify the second FileReader to give a similar output as the first just in an array. What can i do to improve my FileReader so it will give the output i want to? Is there an even easier way maybe?

2
  • what happen if you change reader.readAsBinaryString(file); to fileReader.readAsText(file);? Commented Sep 30, 2019 at 7:22
  • @EhsanKiani It still works the same. Commented Sep 30, 2019 at 7:27

1 Answer 1

1
+50

Try to use a simple model class to store file name and content (replaces your result):

class FileStorage {
   name: string;
   content: any;

   contructor(name: string, content: any) {
      this.name = name;
      this.content = content;
   }
}

Instead of pushing your content / result in the cache, you create a new object with filename and content:

  private readFile(index, files) {
     ...
     reader.onload = (e: any) => {
        this.fileCache.push(new FileStorage(fileName, e.target.result));
     ...

Or you push just a plain object without typing (like in your filereader) ;-)

this.fileCache.push({
        name: fileName,
        content: e.target.result
      });

Now you can get your data via:

  files.forEach((file) => {
        console.log(file.name)
        console.log(file.content)
 }

BTW: Have a look at node.js FileSystem Api, maybe a smarter way to deal with files.

E.g.: tutorialspoint Node FileSystem Examples

API Readfile fs.readfile.

Sign up to request clarification or add additional context in comments.

4 Comments

If I just try to push the plain object i get "Argument of type '{ name: any; content: any; }' is not assignable to parameter of type 'string'."... What could be the cause of this?
It looks like you typed your list (where you pushing ) as a list of Strings?
Your answer is correct thank you very much! I have just one question you might be able to answer... As I am uploading a folder would it be possible to get the name of the folder in the Object too? so that i would have the filename, the file content and the folder name in the object? If so, how could i do this?
Just add another field to your class / object and set your data, e.g.: this.fileCache.push({ fileName: fileName, content: e.target.result, folderName: folderName });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.