I have a problem with single stream and response multi values. The code that does not work:
slugChecker<PipeInput, Out>(
inputController: AbstractControl,
pipeInput: Observable<PipeInput>,
checker: (input: PipeInput & { name: string, slug: string }) => Observable<Out>,
opt?: { debounceTime?: number; ignoreFirstValue?: boolean }
) {
return inputController.valueChanges.pipe(
shareReplay(1),
debounceTime(opt?.debounceTime || 1000), // <= not works correctly
// startWith(true),
skip(opt?.ignoreFirstValue ? 1 : 0), // skip first check for edit mode
switchMap(e => merge(
of(null)
.pipe(tap(_ => console.log('set null'))),
of(e)
.pipe(
// delay(2000), <= bad idea
tap(_ => console.log('run pipe', opt)),
map(input => slugify(input, {
replacement: '-',
remove: /[*+~.()'"!:@]/g,
locale: 'pl',
lower: true,
})),
switchMap(slug => pipeInput.pipe(map(input => ({input, slug})))),
switchMap(({input, slug}) => {
console.log('mapped with ', {input, slug})
return checker({...input, name: inputController.value, slug})
}),
)
),
))
}
I need one stream, so when I write in inputController then stream should emit null.
When the request is done, the value is true or false from the backend (+ false with any error).
Does this draft code debounceTime not work because of the merge?
edit:
Ok, I found soultion :D
slugChecker<PipeInput>(
inputController: AbstractControl,
pipeInput: Observable<PipeInput>,
checker: (input: PipeInput & { name: string, slug: string }) => Observable<boolean>,
opt?: {
debounceTime?: number;
ignoreFirstValue?: boolean,
slugController?: AbstractControl,
}
) {
return merge(
inputController.valueChanges.pipe(
map(_ => null)
),
inputController.valueChanges.pipe(
shareReplay(1),
debounceTime(opt?.debounceTime || 1000),
map(input => slugify(input, {
replacement: '-',
remove: /[*+~.()'"!:@]/g,
locale: 'pl',
lower: true,
})),
switchMap(slug => pipeInput.pipe(map(input => ({input, slug})))),
switchMap(({input, slug}) => {
console.log('mapped with ', {input, slug})
if (opt?.slugController) {
opt.slugController.patchValue(slug)
}
return checker({...input, name: inputController.value, slug})
}),
)
);
}
It works