Reputation: 2034
I'm adding/removing controls from my form based on some conditions.
if(true) {
this.form.addControl('age', new FormControl(this.resp.age));
}
this.form.get('age').valueChanges.subscribe(val => {
//Do something.
});
So what exactly is required here is when a control is added, I need to trigger the valuechanges asosciated with this control. I know that when this control is added and value is set, the valuechanges is not in scope till that time and comes into the picture later. So what can be done here to trigger it when control is added.
Upvotes: 2
Views: 1974
Reputation:
valueChanges need to be triggered by ... Well, a value change. But you can use an operator to change that :
this.form.get('age').valueChanges
.pipe(startWith(this.form.get('age').value))
.subscribe(value => {...});
I actually make several RxJS operators for those kind of questions in my projects, here is this one :
export function firstValueOfControl<T>(control: AbstractControl) {
return control.valueChanges.pipe(startWith(control.value));
}
...
firstValueOfControl(this.form.get('age')).subscribe(value => {...});
Didn't see the if value's present
part. Simply add a filter :
this.form.get('age').valueChanges
.pipe(startWith(this.form.get('age').value), filter(v => !!v)
.subscribe(value => {...});
For the operators :
export function filterTruthy<T>() {
return filter<T>(v => !!v);
}
firstValueOfControl(this.form.get('age'))
.pipe(filterTruthy())
.subscribe(value => {...});
Upvotes: 3
Reputation: 5742
use ngFor inside your template and bind dynamic formControlName.
Template:
<form [formGroup]="formGroup">
...
<ul>
<li *ngFor="let question of questions">
<input [formControlName]="questions.id">
</li>
</ul>
...
</form>
Component:
const questions = [{id: 1}, {id: 2}]; // just for demo
this.formGroup = this.fb.group(
questions.reduce((acc, curr) => ({ ...acc, [curr.id]: '' }), {})
);
This will generate formGroup based on this object: {1: "", 2: "", 3: ""}. If you want, you can also set initial values to the form controls:
const questions = [{id: 1, value: 'q1'}, {id: 2, value: 'q2'}]; // just for demo
this.formGroup = this.fb.group(
questions.reduce((acc, curr) => ({ ...acc, [curr.id]: curr.value }), {})
);
Upvotes: 0