Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

97
Views
RxJS how to grab first values that is not null from two promises

I'm trying to wrap my head around how RxJS concat works, and how it works with Promises in general.

I have two observables:

currentConfirmation$ emits null

newConfirmation$ emits a new confirmation

Could someone explain why this works:

const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap((conf) => {
      if (!conf) {
        return newConfirmation$
      }

      return of(conf)
    })
  )

But this does not

const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))

By not works I mean this test passes with the switchMap version and times out with the concat version

test("updateConfirmation should create the confirmation if it doesn't exist", (done) => {
    updateConfirmation({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' }).subscribe((conf) => {
      expect(conf.entityData).toEqual({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' })
      done()
    })
  })

I would also love to know if there is a better approach to accomplishing the above than what I have come up with.

Edit: Here is all the relevant code for the test:

export const confirmationRepository$ = client$.pipe(
  switchMap(async (client) => client.fetchRepository(schema)),
  delayWhen((cr) => from(cr.createIndex())),
  shareReplay(1)
)

export const updateConfirmation = (newData: Partial<Confirmation>) => {
  // TODO: Just don't process the search if we get empty strings
  const currentConfirmation$ = getConfirmation(newData.symbol || ' ', newData.name || ' ')
  const newConfirmation$ = createConfirmation(newData)

  // const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))
  const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap(async (conf) => {
      if (!conf) {
        return newConfirmation$
      }
      return of(conf)
    }),
    concatAll(),
    combineLatestWith(confirmationRepository$),
    concatMap(async ([conf, confRepo]) => {
      conf.value = !!newData.value
      await confRepo.save(conf)
      return conf
    })
  )

  return finalConfirmation$
}

export const getConfirmation = (symbol: string, name: string) => {
  return confirmationRepository$.pipe(
    switchMap((cr) => cr.search().where('symbol').equals(symbol).and('name').equals(name).first())
  )
}

export const getConfirmations = (symbol: string) => {
  return confirmationRepository$.pipe(switchMap((cr) => cr.search().where('symbol').equals(symbol).returnAll()))
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

concat only executes each observable passed in and returns each of them sequentially, and it does not mutate anything in between nor does it provide any other means to add conditional checks.

I can see your example using find that kinda hack the way through, as it completes the stream when the given condition is met, but it is probably not as semantic or natural as the switchMap version

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!