I am passing from parent an object array which includes a button inside, in this button I have 2 properties, enable and disable the button, and one more to execute a function, the button works fine, when I click the button become disabled, while the request is executing, but once it is finished, it is not enabled again, despite the fact that the this.loading property is false again.
// parent-component.ts
private initForm() {
this.jsonForm = {
controls: [
{
/// code
},
{
type: 'button',
label: 'Send',
disabled: () => this.handleLoading(),
action: (formValue) => this.onSubmit(formValue)
}
]
}
}
handleLoading(): boolean {
return this.loading
}
onSubmit(formValue) {
this.loading = true
this.auth.login(formValue)
.subscribe(
() => {
this.loading = false
},
err => {
this.loading = false
console.log('eror', err)
}
)
}
// parent-component.html
<DynamicForm [jsonForm]="jsonForm"></DynamicForm>
// child-component.html
<ng-container *ngFor="let control of jsonForm?.controls">
<ng-container *ngIf="control.type==='button'">
<UIButton
(click)="control.action(myForm.value)"
[disabled]="control.disabled()">
<span *ngIf="!control.disabled()">{{control.label}} <i *ngIf="icon" class="{{icon}} mr-1"></i></span>
<span class="blink" *ngIf="control.disabled()">Wait <i class="fa fa-spinner fa-spin"></i></span>
</UIButton>
</ng-container>
</ng-container>
Because Angular can't actually detect changes in primitive values.
For example this.loading in the beginning is true, so angular takes the reference of "true" and checks if true changes. True always stays true because you replace it with a completely different value that is "false". Angular can't detect this. Same goes for integers, it can't detect that a 1 has been changed to 0 because it checks it as an object reference not as a value
You need to create a field called:
Then switch in the disabled property (removing handleLoading):
Whenever you want to switch values you use:
and the UI Button should use the async pipe