20

I want to create a component that has attributes that need no value. For example, instead of something like this: (which I have now)

<app-document [mode]="'edit'" ... ></app-document>

or

<app-document [editMode]="true" ... ></app-document>

I would rather have:

<app-document editMode ...></app-document>

So the component itself has to see whether the attribute editMode is present or not. This will look a lot cleaner when I have a lot of such attributes. I haven't seen any documentation on how to do this. Is it doable?

AlanObject
  • 9,613
  • 19
  • 86
  • 142

2 Answers2

34

Material2 wrote the following method:

/** Coerces a data-bound value (typically a string) to a boolean. */
export function coerceBooleanProperty(value: any): boolean {
  return value != null && `${value}` !== 'false';
}

Write something like that in your app-document component:

private _editMode: boolean;
@Input()
get editMode() { return this._editMode; }
set editMode(value: any) { this._editMode = coerceBooleanProperty(value); }

Then:

editMode == true
<app-document editMode></app-document>

editMode == false
<app-document></app-document>

If you use Material2 you can simply import the method as follows:

import {coerceBooleanProperty} from '@angular/cdk/coercion';
Alexandre Annic
  • 9,942
  • 5
  • 36
  • 50
8

You can use boolean @Inputs to achieve this.

HTML:

<app-document [editMode] ...></app-document>

TS:

export class AppDocumentComponent {
  @Input() editMode: boolean = true;
  // ...
}

Now you have a boolean which you can use to change your behavior.

note for better understanding:

The default value true kicks in, if there is a (valueless) attribute. If there is none, editMode does not get the default value but a falsy undefined. (So, that is why this works).

Frank N
  • 9,625
  • 4
  • 80
  • 110
0xcaff
  • 13,085
  • 5
  • 47
  • 55
  • 2
    I didn't think of that pattern but that's pretty clever. If I'm not mistaken the value of editMode is the inverse (boolean not) of what is intuitive but I can live with that. Something like @Input('editMode') notEditMode: boolean = true;. Caffeine and monkeys seem to go together pretty well I guess. – AlanObject May 16 '17 at 00:18
  • 1
    This far simpler approach should have far more votes. – Frank N Apr 10 '19 at 09:51
  • 1
    The problem with this solution is that results in editMode being false. – Thomas Marti Nov 08 '19 at 21:08
  • the problem also is that with @Input we need to use square brackets not really natural – serge May 06 '22 at 13:48
  • " If there is none, editMode does not get the default value but a falsy undefined. (So, that is why this works)." This is not true, it will be true anyway – Desperado Oct 05 '22 at 08:32