Skip to content
Eugene Ghanizadeh edited this page Oct 21, 2021 · 2 revisions
function fetch(url: string | Request, options?: RequestInit): Source<Response>

Sends a request to given URL, and emits the response. Accepts same options as native fetch().

import { fetch, pipe, promise, flatten, map, tap, observe } from 'streamlets'

pipe(
  fetch('https://my.api'),
  map(res => promise(res.json()),
  flatten,
  tap(console.log),
  observe
)

💡 Calls native fetch() under the hood, and if it fails (for example response status is not 200), will end the stream with the given error.


fetch() sends the request and pushes the response when connected to. It can also be pulled, which will cause it to send the request again. This behavior can be used to poll APIs (combine it with pullrate() to avoid spamming the API):

import { pipe, fetch, pullrate, tap, finalize, iterate } from 'streamlets'

// checks every 5s if XKCD is online,
// ends the stream when it goes offline.
pipe(
  fetch('http://xkcd.com/info.0.json'),
  pullrate(5000),
  tap(() => console.log('XKCD is online!')),
  finalize(() => console.log('XKCD is OFFLINE!!!')),
  iterate
)

Try in Sandbox

💡 Will ignore pulls when there is a mid-flight request.


fetch() automatically uses an AbortSignal to cancel mid-flight requests when it is stopped. Combined with cancelling behavior of flatten(), you can avoid stale requests when new information (such as user input) arrives:

HTML Code
<h1>Poké-Search</h1>
<input type="text" />
<pre></pre>
const input = document.querySelector('input')
const pre = document.querySelector('pre')

pipe(
  // get user input
  event(input, 'input'),

  // wait until the user finishes typing
  debounce(500),

  // map the input to an API request (which is the inner stream)
  map((i) => fetch(`https://pokeapi.co/api/v2/pokemon/${i}`)),
  flatten,

  // extract the JSON body of incoming response.
  // this is another inner-stream since it is an async task
  map((r) => promise(r.json())),
  flatten,

  // display the received JSON
  map((v) => JSON.stringify(v, null, 2)),
  tap((v) => (pre.textContent = v)),
  observe
)

Try in Sandbox


👉 fetch() depends on the native fetch(), which is not present in some environments (such as Node). It also requires AbortController. Read this for more info and workarounds.