Reputation: 1517
I have a formControl
with value set to object like {id: 1, name: 'Ramesh'}
. The input field inside mat-form-field is read-only and value either coming from database or selected from a pick list.
To show different view value I am using [value]
binding like below. Its correctly displaying when control is updated later by the user. But when its initialized for the first time with saved value its showing [object Object]
.
Internally its depending upon the order of execution of
DefaultValueAccessor writeValue method
and[value]
binding.
https://stackblitz.com/edit/angular-ivy-mkvx8a?file=src%2Fapp%2Fapp.component.ts
<input readonly [formControl]="userControl" [value]="userControl.value?.name">
I thought to create custom value accessor but it seems too much.
Upvotes: 0
Views: 2020
Reputation: 1517
I have solved it by extending DefaultValueAccessor
and providing custom writeValue
method. But I feel angular should provide a way for just custom writeValue
method.
For example mat autocomplete has displayWith
Demo: https://stackblitz.com/edit/angular-ivy-mkvx8a?file=src%2Fapp%2Fapp.component.html
<input valueKeyAccessor [formControl]="control">
@Directive({
selector: "input[valueKeyAccessor]",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => valueKeyAccessor),
multi: true
}
]
})
export class valueKeyAccessor extends DefaultValueAccessor {
@Input("valueKeyAccessor") propToDisplay;
writeValue: any;
constructor(
_renderer: Renderer2,
_elementRef: ElementRef,
@Optional() @Inject(COMPOSITION_BUFFER_MODE) _compositionMode: boolean
) {
// Refer signature from https://github.com/angular/angular/blob/9.1.11/packages/forms/src/directives/default_value_accessor.ts#L36-L156
super(_renderer, _elementRef, _compositionMode);
// overwriting the writeValue
this.writeValue = value => {
value = value && value[this.propToDisplay];
const normalizedValue =
(value === undefined || value === null) ? "" : value;
super.writeValue(normalizedValue);
};
}
ngOnInit() {
this.propToDisplay = this.propToDisplay || "name";
}
}
Upvotes: 1