debounceTime not works with merge?

Viewed 63

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

0 Answers
Related