4

Im new with angular, and im trying to read a csv file. My problem is when i use ngx-mat-file-input to load a file, i get an error like this:

Uncaught TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.

My html looks like this:

<mat-card class="zone zone-value flex-column">

    <div class="container">
        <h3 mat-dialog-title>Import</h3>

        <!--The followin line works. If use this i can see the file content.-->
        <input type="file" (change)="onChange($event.target.files)">

        <form class="mat-dialog-content" [formGroup]="form" (ngSubmit)="onSubmit(form)" novalidate>

            <div class="form">
                <mat-form-field color="accent">

                    <!--The followin line DOES NOT work.  If use this i can see the file content.-->
                    <ngx-mat-file-input #removableInput [multiple]="multiple" [accept]="accept" [color]="color"
                        formControlName="fileName" placeholder="Load a file"></ngx-mat-file-input>
                    <!-- <button mat-icon-button matSuffix *ngIf="!removableInput.empty" (click)="removableInput.clear($event)">
            <mat-icon>clear</mat-icon>
          </button> -->

                </mat-form-field>
            </div>

            <!-- action buttons-->
            <div mat-dialog-actions>
                <button mat-button [type]="submit" [disabled]="!form.valid">Import</button>
                <button mat-button (click)="closeClick()" tabindex="-1">Cancel</button>
            </div>
        </form>
    </div>

</mat-card>

But when i use the following line, it works, what am i doing wrong?

<input type="file" (change)="onChange($event.target.files)">

Here it shows the content of the csv file. So something is wrong using ngx-mat-file-input

My TS looks like this. I get an error when use the second option to atach a file.

import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Component, Inject } from '@angular/core';
import { Validators, FormGroup, FormBuilder } from '@angular/forms';
import { ThemePalette } from '@angular/material/core';
import { NgxMatFileInputModule, NgxMatFileInputIcon, AcceptValidator, MaxSizeValidator } from '@angular-material-components/file-input';

import { Observable, fromEvent } from 'rxjs';
import { map } from 'rxjs/operators';
import { getMatIconFailedToSanitizeLiteralError } from '@angular/material/icon';

@Component({
  selector: 'csv-parser-dialog',
  templateUrl: 'csv-parser.dialog.html',
  styleUrls: ['csv-parser.dialog.css']
})

export class ImportDataDialogComponent {

  form: FormGroup;

  multiple = false;
  accept = ".csv";
  color: ThemePalette = 'primary';
  maxSize = 1;

  constructor(
    public dialogRef: MatDialogRef<ImportDataDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any,
    private formBuilder: FormBuilder
    ) {

    dialogRef.disableClose = true;
    this.buildForm();
  }

  private buildForm() {
    this.form = this.formBuilder.group({
      fileName: ['', [Validators.required, MaxSizeValidator(this.maxSize * 1024)
      ]]
    });
  }



  fileContent: string = '';

  public onChange(fileList: FileList): void {

console.log('fileList ', fileList);


    let file = fileList[0];
    let fileReader: FileReader = new FileReader();
    let self = this;
    fileReader.onloadend = function(x) {
      console.log('file reader ', fileReader.result);
      //self.fileContent = fileReader.result;
    }
    fileReader.readAsText(file);
    console.log('file reader 2 ', fileReader);
    
  }
  

  readFile(file: File): Observable<any> {

    console.log('file tiene ', file);

    const reader = new FileReader();
    reader.onload = (loadEvent) => (
      console.log('que tiene ', loadEvent.target.result));

    reader.readAsDataURL(file);
    return new Observable;

  }


  onSubmit({ value, valid }: { value: File, valid: boolean }) {

    if (valid) {
      const fileName = value.name;
console.log('size', value.size);

      const fileString = this.readFile(value).subscribe(
        r => {
          console.log('res tiene ', r);
        },
        e => {
          console.log('res tiene ', e);

        });
      this.dialogRef.close({ data: { button: 'EXPORT_BUTTON_CLICKED', dataArray: [] } });
    } else {
      console.log("NOT valid form");
      this.form.markAllAsTouched();
    }
  }

  closeClick() {
    this.dialogRef.close({ data: 'CANCEL_BUTTON_CLICKED' });
  }

  submit() {
    console.log("submited method");
  }

  //Getters form fields
  get fileNameField() {
    return this.form.get('fileName');
  }

}

Someone can help me ?

  • 1
    Not sure I can reproduce the problem. I tried to reproduce it and it works. I can load CSVs without any issue. https://stackblitz.com/edit/angular-ivy-vke5b2 Please check the CSV you're trying to upload for consistency. – Zeeshan S. Aug 10 '20 at 22:37
  • Hi Zeehan, thanks for helping me. My new answer, i can reproduce the error. – Ariel Vattuone Aug 11 '20 at 14:30
  • I updated the code here, in this page, becouse i have not permition to update on stackblitz. If you copy and paste the html and the TS you can reproduce the error. – Ariel Vattuone Aug 11 '20 at 14:35

0 Answers0