Pablo
Pablo

Reputation: 10602

How to check type of variable in ngIf in Angular2

I'm learning Angular2. I have a component with a variable which is an object. I'm iterating over the fields of the object, and acording to the type of data of that position, I need to render a different compoenent. In this case, I want tu render that label if the typeof that position is a number how ever this is not working

<div>
  <div *ngIf='obj'>
    <label *ngFor="let key of keys; let i = index">
      <label class='key'>{{key}}:</label>
      <label class='number' *ngIf='typeof obj[key] === "number"'>
      <!-- label class='number' *ngIf='obj[key] | typeof === "number"' -->
        {{ obj[key] }}
      </label>
    </label>
  </div>
</div>

Any ideas?

I have also created a pipe to get the typeof which work when I print the value, but not inside the *ngIf

Upvotes: 110

Views: 144615

Answers (6)

Fabio Kounang
Fabio Kounang

Reputation: 1

You can simply try this

In your TS set a variable

isNumber = isNaN;

In your template

<p>{{isNumber(your value) ? 'do something' : 'else' }}</p>

Upvotes: 0

Armen Stepanyan
Armen Stepanyan

Reputation: 1848

You can create simple pipe which will receive current item and return item type.

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
  name: 'typeof'
})
export class TypeofPipe implements PipeTransform {

  transform(value: any): any {
    console.log("Pipe works ", typeof value);
    return typeof value;
  }

}

Now you can use typeof pipe in html like this

*ngIf = (item | typeof) === 'number'

And be careful in using function call in your html as mentioned above. It preferred to use pipe instead of function call. Here is Stackblitz example. In first case function call will triggered on any change detection (example: clicking on buttons).

Upvotes: 72

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657366

Globals like window, typeof, enums, or static methods are not available within a template. Only members of the component class and typescript language constructs are available.

You can add a helper method to your component like

isNumber(val): boolean { return typeof val === 'number'; }

and use it like

<label class='number' *ngIf='isNumber(obj[key])'>

Upvotes: 144

Owen
Owen

Reputation: 131

I just tried this and found it won't work in production because function names are shortened. It's safer to use something like:

foo instanceof FooClass

But note that you have to do this in the component/directive because instanceOf is not available in templating:

// In your component
isFoo(candidate){
    return candidate instanceof FooClass;
}

// in your template
{{isFoo(maybeFoo)}}

Upvotes: 8

zurfyx
zurfyx

Reputation: 32767

Alternatively, you can compare the constructor name.

{{ foo.constructor.name === 'FooClass' }}

Detailed info about this here.

Upvotes: 20

tobek
tobek

Reputation: 4539

This is a bit of a hack, but if you need to do this in a lot of places and don't want the cruft of passing some isNumber function around, there's another option that can work if you use it carefully.

You can check for the existence of properties or methods that exist on the prototype of the object or type you're looking for. For example, all numbers have a toExponential function, so:

<label class='number' *ngIf='obj[key] && obj[key].toExponential'>

For functions you could look for call, for strings you could look for toLowerCase, for arrays you could look for concat, etc.

This approach isn't foolproof at all, since you could have an object that happens to possess a property with the same name that you're checking (though if the property you're checking is all you need, then we're basically duck typing), but if you know that the value you have is a primitive you're in good shape, since you can't assign properties on primitives (here is some interesting reading on that topic).

Disclaimer: I don't really trust that this is a good idea and may not be very maintainable or portable, but if you just need something quick for a prototype or a very limited use case, this is a reasonable tool to have in your belt.

Upvotes: 1

Related Questions