8

Hi I am new to Angular and currently I am working with Angular 11 project and there I have to upload a CSV file and extract the records of the file in client side and save them in the database via ASP.NET Web API.

Here I followed a tutorial and tried to get the data of the CSV file in angular side and display them in the same page.

Then I got this error,

Type 'File | null' is not assignable to type 'File'. Type 'null' is not assignable to type 'File'.ts(2322)

I tried so many things but still couldn't solve this. Could you please help me?

This is my .ts file,

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: [
  ]
})
export class FileUploadComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  lines: any = [];
  linesR: any = [];

  changeListener(files: FileList) {
    console.log(files);
    if (files && files.length > 0) {
      let file: File = files.item(0);
      console.log(file.name);
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
        let csv: any = reader.result;
        let allTextLines = [];
        allTextLines = csv.split(/\r|\n|\r/);

        let headers = allTextLines[0].split(';');
        let data = headers;
        let tarr = [];
        for (let j = 0; j < headers.length; j++) {
          tarr.push(data[j]);
        }
        this.lines.push(tarr);
        let tarrR = [];
        let arrl = allTextLines.length;
        let rows = [];
        for (let i = 1; i < arrl; i++) {
          rows.push(allTextLines[i].split(';'));
        }
        for (let j = 0; j < arrl; j++) {
          tarrR.push(rows[j]);
        }
        this.linesR.push(tarrR);
      }
    }
  }
}

This is my .html file

    <div class="container">
    <h1 style="text-align: center"> File Upload </h1>
    <br><br>

    <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">

    <table class="table table-bordered table-dark">
        <thead>
            <tr>
                <th *ngFor="let item of lines[0]; let i = index">
                    {{item}}
                </th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let item of linesR[0]; let i = index">
                <td *ngFor="let itemm of lines[0]; let j = index">
                    {{item[j]}}
                </td>
            </tr>
        </tbody>
    </table>
</div>

This is the error I got

Thank you!

1
  • Change your method like following changeListener(files: File[]). Commented Feb 1, 2021 at 7:52

6 Answers 6

3

Try Using:

fileupload.component.ts

import { Component, OnInit, VERSION } from "@angular/core";
    
@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: []
})
export class FileUploadComponent implements OnInit {
      name = "Angular " + VERSION.major;
    
      lines: any = [];
      linesR: any = [];
    
      ngOnInit() {}
    
      changeListener(files) {
        let fileList = (<HTMLInputElement>files.target).files;
        if (fileList && fileList.length > 0) {
          let file: File = fileList[0];
          console.log(file.name);
          console.log(file.size);
          console.log(file.type);
    
          let reader: FileReader = new FileReader();
          reader.readAsText(file);
          reader.onload = e => {
            let csv: any = reader.result;
            let allTextLines = [];
            allTextLines = csv.split(/\r|\n|\r/);
    
            let headers = allTextLines[0].split(";");
            let data = headers;
            let tarr = [];
            for (let j = 0; j < headers.length; j++) {
              tarr.push(data[j]);
            }
            this.lines.push(tarr);
            let tarrR = [];
            let arrl = allTextLines.length;
            let rows = [];
            for (let i = 1; i < arrl; i++) {
              rows.push(allTextLines[i].split(";"));
            }
            for (let j = 0; j < arrl; j++) {
              tarrR.push(rows[j]);
            }
            this.linesR.push(tarrR);
          };
        }
      }
    }

fileupload.component.html

<div class="container">
  <h1 style="text-align: center">File Upload</h1>
  <br /><br />

  <input
    class="form-control"
    type="file"
    class="upload"
    (change)="changeListener($event)"
  />

  <table class="table table-bordered table-dark">
    <thead>
      <tr>
        <th *ngFor="let item of lines[0]; let i = index">
          {{item}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let item of linesR[0]; let i = index">
        <td *ngFor="let itemm of lines[0]; let j = index">
          {{item[j]}}
        </td>
      </tr>
    </tbody>
  </table>
</div>
Sign up to request clarification or add additional context in comments.

6 Comments

Hi Msk, thank you so much. I tried your answer like this, changeListener(files: File[]) { // const file: File | undefined = files?.item(0); console.log(files); console.log(files[0]); var file: File = files[0]; //if (file && files.length > 0) { if (files && files.length > 0) { let file: File = files.item(0); console.log(file.name); console.log(file.size); console.log(file.type); and now I am getting this error, Property 'item' does not exist on type 'File[]'. let file: File = files.item(0); Could you please help me?
you can get the file with files[0]
I have updated the answer .get the file from files array as follows let file: File = files[0]; not use files.item(0)
Hi I tried your answer. Now I am getting errors in .html file like this, Object is possibly 'null'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)"> Property 'files' does not exist on type 'EventTarget'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">
try this stackblitz example, stackblitz.com/edit/…
|
3

Another solution is like -

let file: File | any = null;

OR

let file: File | null = null;

Comments

1

If you are sure about that you will have values into files item then you can say :

let file: File = files.item(0) as File;

1 Comment

Hi thanks I tried it and now it is giving this error, error TS2531: Object is possibly 'null'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)"> error TS2339: Property 'files' does not exist on type 'EventTarget'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">
1

You are using strict: true with typescript. That's good! The issue you are facing though is that this piece:

let file: File = files.item(0);

can return undefined, even though you check for the length before. This would make the type File | null , but you are stating it should just be File.

Better would be to change it to the following:

changeListener(files: FileList) {
 const file: File | null = files?.item(0);

 if (file) {
   // here `file` will have type `File` because it has been asserted with the `if`
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
  //...
 

2 Comments

Hi Poul thank you so much. I tried your answer like this, changeListener(files: FileList) { const file: File | undefined = files?.item(0); console.log(files); if (file && files.length > 0) { //if (files && files.length > 0) { //let file: File = files.item(0); console.log(file.name); console.log(file.size); console.log(file.type); and now I am getting this error. Type 'File | null' is not assignable to type 'File | undefined'. Type 'null' is not assignable to type 'File | undefined'.ts(2322) Could you please help me?
@kalpana Correct, if item does not exist, it will return null instead of undefined. I've updated my answer
1

If u want to make a file Null do this file= new File([],''); It will reinitialize the file object to an empty file object

Comments

0

I've got no problem with this:

const file = files.item(0);
if (file && file !== null) {
  ...

and this:

const file: any = files.item(0);
if (file && file !== null) {
  ...

And even if I'm using files[0] instead of files.item(0). And all this in strict mode.

2 Comments

Hi thanks I tried it and now it's giving this error, Object is possibly 'null'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)"> Property 'files' does not exist on type 'EventTarget'. <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">
I've updated my answer. Now I see another problem in your error: Property 'files' does not exist on type 'EventTarget'. You can and you MUST solve that one before you can fix the item(0) thing. Maybe try files: Event instead of just files in the parameters section.

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.