Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean inputs to angular 2 component

Tags:

angular

I'm trying to write a component to be reused across my application, which will sometimes show a control button and sometimes not.

Ideally, I'd want to get this from the presence or absence of an attribute, so that using the component would look something like <generic-component hideControls></generic-component>, with a boolean variable in my component based on whether that attribute is present, but I can't see a way to do this.

Is there a way to do this?

I have tried with the slightly more messy version below (although ideally I would not need to set a value on showControls/hideControls);

generic.component.html

<div>
  <div>Stuff</div>
  <div *ngIf="showControls">Controls</div>
</div>

generic.component.ts

// imports etc.
@Component({
  selector: 'generic-selector',
  templateUrl: 'generic.component.html'
})
export class GenericComponent implements OnInit {
  @Input()
  public showControls: boolean = true;

  // other inputs and logic
}

This fails, because the usage <generic-selector showControls="false"></generic-selector> sets showControls as the string "false", which is truthy, rather than as the boolean value. So I have to get round it by adding a lot of mess to the component to take in the input and convert to a boolean based on whether it is being given the string "false" or not. A non-messy way to sort this would be appreciated, but I'd prefer being able to do the other option above.

like image 900
meta Avatar asked May 09 '17 15:05

meta


People also ask

What is@ input in Angular?

@Inoput decorator is used to pass data (property binding) from parent to child component. The component property should be annotated with @Input decorator to act as input property. Let's explore it practically. I have created an angular application which is AngApp. I have created two components.

What is the difference between@ input and@ Output in Angular?

@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.

What is Boolean in Angular?

The boolean is a primitive type in Typescript. It represents a simple true/false value. They are implemented as numerical values with a single binary digit (i.e., 0 & 1). The Boolean is an object wrapper for the primitive boolean value.


3 Answers

This fails, because the usage <generic-selector showControls="false"></generic-selector> sets showControls as the string "false", which is truthy, rather than as the boolean value. So I have to get round it by adding a lot of mess to the component to take in the input and convert to a boolean based on whether it is being given the string "false" or not. A non-messy way to sort this would be appreciated, but I'd prefer being able to do the other option above.

using binding

<generic-selector [showControls]="false"></generic-selector>
like image 175
Tiep Phan Avatar answered Oct 21 '22 19:10

Tiep Phan


You can use the Input decorator as you would normally do with other attributes. The only trick is that when the attribute is non-present, the value would be undefined, otherwise, the value would be an empty string.

Logic:

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

@Component({
  selector: '',
  templateUrl: './boolean-component.component.html'
})
export class AppBooleanComponent implements OnInit {

  @Input('boolean-attribute') booleanAttr: boolean;

  ngOnInit() {
    this.booleanAttr = this.booleanAttr !== undefined;
    console.log(`Boolean attribute is ${this.booleanAttr ? '' : 'non-'}present!`);
  }

}

Template 1 (logs 'Boolean attribute is present!'):

<app-boolean-component boolean-attribute></app-boolean-component>

Template 2 (logs 'Boolean attribute is non-present!'):

<app-boolean-component></app-boolean-component>
like image 25
Ramtin Soltani Avatar answered Oct 21 '22 21:10

Ramtin Soltani


In Angular there are two ways to assign a value to your property:

  1. using as HTML attribute
  2. with square brackets

In the first case, the value of your property will always be a string, like every HTML attribute even if you'll assign an interpolable string like this: {{true}}.

While in the second case, it'll be interpreted as a JavaScript expression but in your context. So if you'll have an object notation there the value of your attribute will be the parsed as an object. But for specifying context angular is not using "with" statement so you can't use your globals there, but only the properties of the component in which scope your component is inserted.

<generic-selector [showControls]="false"></generic-selector>

In this case, it takes the string "false" and translates it to JavaScript. So in JavaScript, it's a boolean, then you'll get it as a boolean.

But if you'll have something like this: <generic-selector [showControls]="{myProp: 'val'}"></generic-selector>

then the type of your showControls will be object and its value will have myProp property equal to 'val'.

but if you'll have some nonliteral there then it'll be considered to be a property of your class:

<generic-selector [showControls]="location"></generic-selector>

then if you'll have a location property on the scope of the component containing your generic-selector then the value of its location property will be taken otherwise it'll be undefined.

I'll suggest you to consider using ngOnInit for logging the property's type and the value assigned.

like image 14
hakobpogh Avatar answered Oct 21 '22 21:10

hakobpogh