3
Compiled with problems:X
ERROR
src/app/components/users/users.component.html:2:22 - error TS2532: Object is possibly 'undefined'. 

2 <ul *ngIf="loaded && users?.length > 0">
                       ~~~~~~~~~~~~~~~~~
  src/app/components/users/users.component.ts:6:16
    6   templateUrl: './users.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component UsersComponent.

This is my error. I have been looking around whithout much luck. My experience with angular or typescript is very limited. I am actualy following a udemy course. This is the first time I am encountering "Optional Chaining" so I might be overlooking something obvious.

The code that produces the issue is fairly simple

<h2>Users</h2>
<ul *ngIf="loaded && users?.length > 0">
  <li *ngFor="let user of users">
    <h3>{{ user.firstName }} {{ user.lastName }}</h3>
    <ul *ngIf="showExtended">
      <li>age: {{ user.age }}</li>
      <li>Address: {{ user.address.street }} {{ user.address.city }} {{ user.address.state }}</li>
    </ul>
  </li>
</ul>

The component.ts just provides a users[] But the coarse was trying to explain some sort of loading animation. Thats why the users[] sometimes is not loaded from the start.

Any help is appreciated.

Ric Bocad
  • 45
  • 1
  • 5

3 Answers3

1

It seems to me that you're running in strict mode which is good, but for someone that just started with TS and Angular can be overwhelming.

This line here users?.length > 0 throws an error because the users list can be undefined so in the strict mode you cannot compare undefined to a number (as per the error message in your console) and the safety operator is not enough to get rid of that error.

If you know that the users list cannot be undefined, you can use the definite assertion operator ! like so

users!.length > 0

But the best option is to check that your list is not undefined before comparing the length and you can do it like so:

!!users && users.length

Your condition will also work like this:

users?.length

By not comparing it to a number, the error won't be thrown and now that expression covers null, undefined and 0 values.

ionut-t
  • 1,121
  • 1
  • 7
  • 14
  • Why to use double !! before the users? When you check only users you will not pass if it is undefined. The double !! is because of the strict mode as well? – Vítor França Dec 11 '21 at 19:14
  • !! operator evaluates the users list to a boolean. So if it's undefined or null it will be false, otherwise, it will be true. It seems that this approach works better for me in the strict mode (I had strange errors when I didn't use it like that in some cases). But sure, you can try using the negation only. – ionut-t Dec 11 '21 at 19:23
  • He is already using optional chaining - you replace that with the bang operator, which does the same. At least type-wise. This is just a bad practice. – pascalpuetz Dec 11 '21 at 19:50
  • I will give this a try once i get home from work. I like that you explained all of the diffrences. If it works I wil select this as the correct answer! – Ric Bocad Dec 12 '21 at 01:42
0

The error that you have explain: users is a object and not a array.

The arrays can validate with: array.length

So, the idea is:

  1. If users is a object, you can validate with: <ul *ngIf="loaded && users">

  2. If users is a array, you must change the data configurations on the controller.ts

0

I thing one way is check if users is defined as part of the if condition

"loaded && users && users?.length > 0"