0

If I have a template like this (readOnly is a boolean and arrayOfStuff is an array):

<span *ngIf="!readOnly && arrayOfStuff && arrayOfStuff.length">Hey</span>

ng build --prod orng serve --prod both give the error:

ERROR in /Development/project/src/$$_gendir/app/components/thing/thing.component.ngfactory.ts (767,11): Type 'number' is not assignable to type 'boolean'.

...but if I remove the boolean check it works fine:

<span *ngIf="arrayOfStuff && arrayOfStuff.length">Hey</span>

...or if I make the length check specifically a numeric comparison it works fine:

<span *ngIf="!readOnly && arrayOfStuff && (arrayOfStuff.length >0)">Hey</span>

Why is it OK to do a falsy check against arrayOfStuff.length when I'm checking if an object exists, but it is not OK to do this when I'm checking the value of a boolean along with it?

Again, this only happens when I am actually generating a production build with ng build --prod or ng serve --prod. It is not a problem for development.

To be clear - I can make the problem go away, but I want to understand why it is OK to check arrayOfStuff.length directly in one case, and not in the other.

Angular v4, @angular/cli v1.0.1.

WillyC
  • 3,917
  • 6
  • 35
  • 50
  • this is a typical behavior and happens because of AOT. Angular cli uses AOT by default when you use `--prod` – Ahmed Musallam Apr 25 '17 at 18:33
  • I guessed that, but what are the specific rules that must be followed? Why does AOT allow a comparison that includes a number and checking if an object exists, but doesn't allow you to compare those two along with a boolean? – WillyC Apr 25 '17 at 18:37
  • the AOT compiler analyzes the html statically. And it is looking for a very specific type, in the case of `ngIf` its a boolean. When you use `JIT` javascript runtime (browser) will convert objects to boolean via truthy/falsy mechanism. – Ahmed Musallam Apr 25 '17 at 18:43
  • 1
    Right - but in one of the examples that works correctly, none of the types are a boolean and it still works. Why does it accept it in this case but not in the case when a boolean IS one of the types? Specifically this works, but should not based on your explanation: `Hey` – WillyC Apr 25 '17 at 18:45

1 Answers1

1

When you do not use comperators javascript tries to use type-coercion on variables. Since it tries it in here and cannot change it directly to boolean it gives you error. However when you make it

array.length > 0

it does not try that because all variables are boolean. Apperantly problem is that primitive number cannot be changed to boolean. You can use

!!array.length 

to get your desired result

necilAlbayrak
  • 824
  • 6
  • 9
  • That doesn't explain why `Hey` works correctly and only stops working once a boolean is added to the mix. I'm trying to determine the rules that govern this - I had already obtained a workaround using the first method you suggest. – WillyC Apr 25 '17 at 18:47