JMon
JMon

Reputation: 3447

TS2531: Object is possibly 'null'

I have the following function:-

uploadPhoto() {
    var nativeElement: HTMLInputElement = this.fileInput.nativeElement;

    this.photoService.upload(this.vehicleId, nativeElement.files[0])
        .subscribe(x => console.log(x));
}

however on the nativeElement.files[0], I am getting a typescript error, "Object is possibly 'null'". Anyone can help me solve this issue?

I tried to declare the nativeElement as a null value, however did not manage to succeed.

Thanks for your help and time.

Upvotes: 64

Views: 169269

Answers (8)

Ahmad
Ahmad

Reputation: 56

The error occurs because TypeScript's type checking indicates that nativeElement.files might be null. This happens because HTMLInputElement.files can indeed be null if no file is selected in the input element.

To resolve this, you need to add a null check to ensure that files is not null before attempting to access it:

uploadPhoto() {
    const nativeElement: HTMLInputElement = this.fileInput.nativeElement;

    if (nativeElement.files && nativeElement.files[0]) {
        this.photoService.upload(this.vehicleId, nativeElement.files[0])
            .subscribe(x => console.log(x));
    } else {
        console.error("No file selected.");
    }
}

Upvotes: 0

Wlado87
Wlado87

Reputation: 1

Thank you. I had the same issue. In older version Ionic was all right. After update TS2531. Now the function have two non-null assertion operator:

async saveToStorage(jsonMessage){
  await this.storage.set(jsonMessage["key"],jsonMessage["value"]);
  document.getElementsByTagName('iframe').item(0)!.contentWindow!.postMessage'{"type": "storage-save","result": "ok","key": "' + jsonMessage["key"] + '"}',"*");
}

Upvotes: 0

maulik rupareliya
maulik rupareliya

Reputation: 1

app.component.html

Enter your Name :<input [value]="data1" (input)='data1=$event.target.value'><br>
Enter name :{{data1}}

app.component.ts

data1:any = 'yash';

Upvotes: -2

Nitin Bisht
Nitin Bisht

Reputation: 271

In addition to all the answers mentioned above, still if the user doesn't want the strict null checks in its application, we can just simply disable the strictNullChecks property in our tsconfig.json file.

{
 ...
 "angularCompilerOptions": {
 "strictNullChecks": false,
 ...
 }
}

Upvotes: 18

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

files is defined to be FileList | null so it can be null.

You should either check for null (using an if) or use a "Non-null assertion operator" (!) if you are sure it is not null:

if(nativeElement.files != null) {
    this.photoService.upload(this.vehicleId, nativeElement.files[0])
        .subscribe(x => console.log(x));
}

//OR
this.photoService.upload(this.vehicleId, nativeElement.files![0])
    .subscribe(x => console.log(x));

Note:

The "Non-null assertion operator" will not perform any runtime checks, it just tells the compiler you have special information and you know nativeElement.files will not be null at runtime.

If nativeElement.files is null at runtime, it will generate an error. This is not the safe navigation operator of other languages.

Upvotes: 93

Jamie
Jamie

Reputation: 4335

Using the answer from Markus which referenced optional chaining, I solved your problem by casting nativeElement to HTMLInputElement and then accessing the 0th file by using .item(0) with the optional chaining operator ?.

uploadPhoto() {
    var nativeElement = this.fileInput.nativeElement as HTMLInputElement

    this.photoService.upload(this.vehicleId, nativeElement?.files?.item(0))
        .subscribe(x => console.log(x));
}

Upvotes: 2

Vayrex
Vayrex

Reputation: 1467

If you are sure that there is a file in all cases. You need make compiler to be sure.

(nativeElement.files as FileList)[0]

Upvotes: 6

Markus
Markus

Reputation: 4242

TypeScript 3.7 got released in 11/2019. Now "Optional Chaining" is supported, this is the easiest and most secure way of working with potentially null-able values:

You simply write:

nativeElement?.file?.name

Note the Question-Mark! They check for null/undefined and only return the value, if none of the properties (chained with dots) is null/undefined.

Instead of

if(nativeElement!=null && nativeElement.file != null) {
  ....
}

But imagine something more complex like this: crm.contract?.person?.address?.city?.latlang that would otherwise a lot more verbose to check.

Upvotes: 38

Related Questions