Search code examples
cyclejsxstream-js

Storing REST response to indexedDB with Cycle.js


I'm in the middle of learninig Cycle.JS and ran into a challenge. I have a component that will get a result from an HTTP call and I'd like to persist this response in indexDB. However, I feel that the request for persistence is the responsibility of another component.

The questions I have are:

  1. Is this a use case for a custom driver that persists HTTP responses to indexDB?
  2. How does another component access the response stream for a request it did not make?
  3. When I try to select the category from the HTTP source, nothing gets logged to the console. I'm using xstream, so the streams should be hot and I expect debug to output. What's going on here?

Below is my component that makes the HTTP call:

import { Feed } from './feed'

export function RssList ({HTTP, props}, feedAdapter = x => x) {
  const request$ = props.url$
    .map(url => ({
      url: url,
      method: 'GET',
      category: 'rss'
    }))

  const response$ = HTTP
    .select('rss')
    .flatten()
    .map(feedAdapter)

  const vDom$ = response$
    .map(Feed)
    .startWith('')

  return {
    DOM: vDom$,
    HTTP: request$
  }
}

Here is my attempt at accessing the response at the app level:

export function main (sources) {
  const urlSource = url$(sources)
  const rssSink = rss$(sources, urlSource.value)

  const vDom$ = xs.combine(urlSource.DOM, rssSink.DOM)
    .map(([urlInput, rssList]) =>
      <div>
        {urlInput}
        {rssList}
      </div>
    )

  sources.HTTP.select('rss').flatten().debug() // nothing happens here

  return {
    DOM: vDom$,
    HTTP: rssSink.HTTP
  }
}

Solution

  • Selecting a category in the main (the parent) component is the correct approach, and is supported.

    The only reason why sources.HTTP.select('rss').flatten().debug() doesn't log anything is because that's not how debug works. It doesn't "subscribe" to the stream and create side effects. debug is essentially like a map operator that uses an identity function (always takes x as input and outputs x), but with a logging operation as a side effect. So you either need to replace .debug() with .addListener({next: x => console.log(x)}) or use the stream that .debug() outputs and hook it with the operator pipeline that goes to sinks. In other words, debug is an in-between logging side effect, not a destination logging side effect.