I am trying to use the combineLatest with reactive form's valueChanges method in NgOnInIt hook. My use case is below.
I want to show the name which received from Observable1$ in the form using patchValue() from Reactive forms. This name field is editable which means when user wants to edit the name which is already shown in the form, I want to check if the name is not the same and if it is not then I want to enable the button to call PUT method. Hence, I want to use combineLatest from RxJS to handle this behavior but I am not able to do that so. Below errors I am getting.
Actual Behaviours:
Expected behaviour:
Formfield should show the data which I received from observable1$ (ex: testName). When I want to edit this field (ex: testNameE), valueChanges method should emit {description: testNameE} value.
How I am trying to achieve this.
form-component.ts
ngOnInit() {
combineLatest([
this.observable1$.pipe(startWith(null)), - provides name
this.form.valueChanges.pipe(startWith(null)), - wants to get the input from the user when he tried to change the name
]).pipe(
tap(([name, formData]) => {
if (name) {
this.patchValue(name);
}
if (formData) {
// check the name is different than received from observable1$,
// if yes, enable button
}
}),
).subscribe();
}
patchValue(name: string) {
this.form.patchValue({
name: name,
});
this.form.updateValueAndValidity();
}
Can someone please tell me what I am doing wrong here. Any kind of help is appreciated.
Below is the link for stackblitz. https://stackblitz.com/edit/angular-ivy-zjpwxb?file=src/app/app.component.ts
I think the simplest solution here is to separate out the patch form logic to only depend on observable1$
and not value changes
My personal preference is to not use tap
unless debugging or explicitly doing mid stream side effects i.e. I'm using async pipe so can't subscribe.
ngOnInit() {
// patch name to form
this.observable1$.pipe(
filter(v => !!v),
takeUntil(this.destroyed$)
).subscribe(name => this.patchValue(name))
// for use with a async pipe
this.showSaveButton$ = combineLatest([this.observable1$, this.form.valueChanges])
.pipe(
filter(([name, _]) => !!name)
map(([name, formData]) => {
// check different
return name !== formData.name
}),
takeUntil(this.destroyed$),
startWith(false)
)
}
patchValue(name: string) {
this.form.patchValue({
name: name,
});
this.form.updateValueAndValidity();
}