I have an Observable<FormGroup>
that has a couple of boolean FormControl
readonly someForm$ = model$.pipe(map((model: Model) => {
return new FormGroup({
foo: new FormControl(model.getFoo()),
bar: new FormControl(model.getBar()),
});
}));
I would like to create an observable that emits if any of the FormControl
values are true
. I tried the following
readonly result$ = someForm$.pipe(switchMap(
form => form.valueChanges.pipe(
map(changes => changes.foo || changes.bar),
startWith(() => form.value['foo'] || form.value['bar'])
)
));
Though result$
always resolves to true
during testing. What is the proper way to create an observable that is essentially foo || bar
?
Minimal example: https://stackblitz.com/edit/angular-material-bvy7bj
CodePudding user response:
There're several issues:
You have
result$
in your component and$result
in your template.startWith()
doesn't accept a function, it needs to be a value in your use-case.You make two subscriptions to
someForm$
which creates two unrelatedFormGroup
instances. You'll need to useshareReplay(1)
at the end ofsomeForm$
.
Your updated demo: https://stackblitz.com/edit/angular-material-xpqmcs?file=app/app.component.ts
CodePudding user response:
use filter
operator to filter out falsey values
const result$ = someForm$.pipe(
switchMap((form) =>
form.valueChanges.pipe(
filter((changes) => changes.foo || changes.bar),
map((changes) => changes.foo || changes.bar)
)
)
);
I have created simulated form and simulated user events
import { BehaviorSubject, of } from 'rxjs';
import { filter, map, startWith, switchMap } from 'rxjs/operators';
const someForm$ = of({ // custom Observable form
valueChanges: new BehaviorSubject({
foo: false,
bar: false,
}),
value: {
foo: false,
bar: false,
},
});
const result$ = someForm$.pipe(
switchMap((form) =>
form.valueChanges.pipe(
filter((changes) => changes.foo || changes.bar), // filtering falsey values
map((changes) => changes.foo || changes.bar) // map to true
)
)
);
result$.subscribe((data) => {
console.log(data);
});
someForm$.subscribe((data) => {
data.valueChanges.next({ foo: false, bar: true }); // custom user event
data.valueChanges.next({ foo: false, bar: false }); // custom user event
data.valueChanges.next({ foo: true, bar: false }); // custom user event
});
demo:
https://stackblitz.com/edit/typescript-tfqjms?file=index.ts&devtoolsheight=100