I am starting with Angular basics, I have the below code to assign a class to a button based on the button name which is received as a prop like below in component.ts file,
import { Component, Input } from '@angular/core';
import type { ButtonProps } from './reuseable-button-types';
@Component({
selector: 'button',
standalone: true,
imports: [],
templateUrl: './button.component.html',
styleUrl: './button.component.css',
})
export class ReusableButtonComponent {
@Input({ required: true })
buttonProps: ButtonProps = {
buttonName: '',
handleClick: () => {
//
},
};
}
button.component.html =>
<button
(click)="buttonProps.handleClick()"
class="reusable-button {{ buttonProps.buttonClass }}"
type="button"
[class.yes-button]="buttonProps.buttonName === 'Yes'"
[class.no-button]="buttonProps.buttonName === 'No'"
>
{{ buttonProps.buttonName }}
</button>
The above code works fine with 'yes-button' and 'no-button' class names getting assigned to the button when the button name is 'Yes' or 'no'. But when I assign the value to a variable inside the component.ts file classes are not getting assigned as expected. See the below code.
button.component.ts =>
import { Component, Input } from '@angular/core';
import type { ButtonProps } from './reuseable-button-types';
@Component({
selector: 'button',
standalone: true,
imports: [],
templateUrl: './button.component.html',
styleUrl: './button.component.css',
})
export class ReusableButtonComponent {
@Input({ required: true })
buttonProps: ButtonProps = {
buttonName: '',
handleClick: () => {
//
},
};
isYesButton = this.buttonProps.buttonName === 'Yes';
isNoButton = this.buttonProps.buttonName === 'No';
}
button.component.html =>
<button
(click)="buttonProps.handleClick()"
class="reusable-button {{ buttonProps.buttonClass }}"
type="button"
[class.yes-button]="isYesButton"
[class.no-button]="isNoButton"
>
{{ buttonProps.buttonName }}
</button>
When we write the class evaluation variables like below
isYesButton = this.buttonProps.buttonName === 'Yes';
isNoButton = this.buttonProps.buttonName === 'No';
They are only evaluated once during component load and not after that, but you want this to be more dynamic, so I suggest you can go for getter
method, which will be evaluated each time the property is accessed and you will get the dynamic behavior you are expecting!
get isYesButton() {
return this.buttonProps.buttonName === 'Yes';
}
get isNoButton() {
return this.buttonProps.buttonName === 'No';
}
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
standalone: true,
imports: [],
template: `
<button
(click)="handleButtonClick()"
class="reusable-button {{ buttonProps.buttonClass }}"
type="button"
[class.yes-button]="isYesButton"
[class.no-button]="isNoButton"
>
{{ buttonProps.buttonName }}
</button>
`,
})
export class ChildComponent {
@Input({ required: true }) buttonProps: any = {
buttonName: '',
buttonClass: 'test',
handleClick: () => {
console.log('click');
},
};
get isYesButton() {
return this.buttonProps.buttonName === 'Yes';
}
get isNoButton() {
return this.buttonProps.buttonName === 'No';
}
handleButtonClick() {}
}
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { ChildComponent } from './app/child/child.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [ChildComponent],
template: `
<app-child [buttonProps]="buttonProps"/>
`,
})
export class App {
name = 'Angular';
buttonProps = {
buttonName: 'Yes',
handleClick: () => {
console.log('click');
},
};
ngOnInit() {
setInterval(() => {
this.buttonProps.buttonName =
this.buttonProps.buttonName === 'Yes' ? 'No' : 'Yes';
}, 2000);
}
}
bootstrapApplication(App);