Home > Blockchain >  Angular component attribute without value nor square brackets
Angular component attribute without value nor square brackets

Time:05-07

I need to add the isBold property to an Angular component

<child-component isBold />

Remark the following

  • I prefer do not use square brackets [] around the property name if used as true flag (as in the code above, long version would be isBold = true).

  • However I would like to be able to use it as an input property

    <child-component [isBold]="parentBooleanOrFunction" />
    

the code bellow breaks the first requirement

@Input() isBold: boolean = true

Is there a way, in Angular 13, to do it without writing additional helper functions?

I note I read the similar question here, but the selected solution needs additional code or Material usage I have not.

CodePudding user response:

You can use directive to do that but it will not work as an ordinary @Input

Working examople on stackblitz

Create input directive

@Directive({
  selector: '[isBold]'
})
export class IsBoldDirective {

  @Input() isBold:boolean;

  constructor() { }

  ngOnInit(){
    if(this.isBold!==false){
      this.isBold=true; // defaults to true
    }
  }
}

Inject it into the component

@Component({
  selector: 'app-testing',
  templateUrl: './testing.component.html',
  styleUrls: ['./testing.component.css']
})
export class TestingComponent {
  constructor(@Self() @Optional() private isBold:IsBoldDirective) { }
  get value(){
    return this.isBold?.isBold ?? true; // this 'true' is the default value if isBold is not there
  }
}

and use it like this

Absence: <app-testing></app-testing>
Presence: <app-testing isBold></app-testing>
Set value: <app-testing [isBold]="false"></app-testing>

with result

Absence:

true
Presence:

true
Set value:

false 

CodePudding user response:

To achieve that, I would suggest creating your own coercion functions/types similar to the Angular CDK functions/types (If you don't need to add the @angular/cdk to your project dependencies), which are very easy to implement than creating a directive for each Input:

/**
 * Type describing the allowed values for a boolean input.
 * @docs-private
 */
export type BooleanInput = string | boolean | null | undefined;

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

Then you can use them directly in any component, like the following:

@Input()
get isBold(): boolean {
  return this._isBold;
}
set isBold(isBold: BooleanInput) {
  this._isBold = coerceBooleanProperty(isBold);
}
private _isBold = false;
<child-component isBold />
<child-component [isBold]="parentBooleanOrFunction" />

You can find the full list of Angular CDK coercion functions/types under angular/components/src/cdk/coercion/: https://github.com/angular/components/tree/main/src/cdk/coercion

  • Related