A button gets clicked, performs an action, and a success message gets shown briefly, based on the boolean values in the stream.
let copied: Observable<boolean> = fromEvent(button, "click").pipe(
mergeMap(() => navigator.clipboard.writeText(...)), // writeText returns a promise
switchMap(() => [of(true), of(false).pipe(delay(1000))]),
startWith(false),
);
Obviously this doesn't work, as I've got Observables in switchMap, not values.
We need false -> Click -> perform action -> true -> delay -> false
Note, if the button is quickly clicked again, the message shouldn't disappear (hoping to solve the obvious race condition).
Your code is close. Instead of returning an array inside your switchMap
, return an observable that emits the two values you want. You can use concat
to create a single observable from your two sources of(true)
and of(false).pipe(delay(1000))
:
const copied: Observable<boolean> = fromEvent(button, 'click').pipe(
mergeMap(() => navigator.clipboard.writeText('')),
switchMap(() => concat(of(true), of(false).pipe(delay(1000)))),
startWith(false),
);