npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

async-stuff

v0.1.0

Published

Fetch and render asynchronous stuff like you mean it

Downloads

13

Readme

Remote Data


Work In Progress!

Just using this readme to tinker with the idea!!


  • add jest

  • add eslint

  • add prettier

  • Write the js lib

  • add CI + badge

  • Write the react component (with examples)

  • Write the vue component (with examples)

  • How does Vue reactivity works with that?

  • add flow?

Write implementations for:

  • [ ] React

  • [ ] Vue

  • [ ] Vanillajs

  • [ ] Angular1

  • [ ] Angular2

  • [ ] Polymer

  • [ ] Ember

  • [ ] Aurelia

  • [ ] Preact

  • store the query params, cache result

  • add a noCache version of it


Thanks to krisajenkins and his original implementation in Elm

A framework agnostic js utility to render remote data.

Often you want to render data fetched from your server in a page. But quickly the data structure starts to look like this:

{
  loading: false,
  fetched: false,
  data: [],
  errors: null
}

...and that leaves you the tedious tasks of syncing this state and checking booleans in your interface to render a spinner, the data, and so on.

This library allows you to simplify all these decisions (do you name it loading? or pending? what the errors look like?) by abstracting all this process.

The more useful use case will be to use a RemoteData instance in the state of your application, and have a component that abstract the rendering.

Let's see how that would work with React.

Usage

With React

First, the state.

class ThingsList extends React.Component {
  state = {
    things = new RemoteData('http://httpbin.org/get?data=a&data=b&data=c')
  }

  componentWillMount() {
    this.state.things.fetch()
  }

  // render() ?
}

Whether the state comes from redux, a component local state or anything else does not really matter.

Here we use a custom component to render our remote data. You don't have to, but it's a nice thing to do. Our custom component will be composed of our common application spinner, error rendering, and so on.

// example with a render props.

const CustomRemoteDataRendering = ({render, src}) => {
  render() {
    if (src.isNotAsked()) {
      return null
    }

    if (src.isPending()) {
      return <Spinner/>
    }

    if (src.isFailed()) {
      return <div>{src.error.toString()}</div>
    }

    return render(src.content)
  }
}

// or this? not sure yet...
const CustomRemoteDataRendering = ({render, src}) => {
  render() {
    switch (src.status()) {
      case NOT_ASKED:
        return null
      case PENDING:
        return <Spinner/>
      case FAILED:
      return <div>{src.error.toString()}</div>
      default:
        return render(src.content)
    }
  }
}

Or if you want to use our component:

const CustomRemoteDataRendering = (props) => (
  <RemoteData
    notAsked={BlankComponent}
    pending={() => <p>loading...</p>}
    error={error => <Alert>{error.message}</Alert}
    ok={content => <ListOfThings {...content}/>}
    {...props}
  />
)

This component provide sane defaults for the notAsked, Pending and Error component, so you don't have to fill them all.

This component can be reused anywhere in your app, as It is used to manage the lifecycle of the request. But the rendering is given back to the parent component using a render prop.

Now let's render the remote data back in our first component:

class ThingsList extends React.Component {

  // same as before

  render() {
    <CustomRemoteDataRendering
      src={this.state.things)
      render={(content) => (
        <ul>
          {content.map(thing => <li>{thing</li>})}
        </ul>
      )}
    />
  }

  // or

  render() {
    <CustomRemoteDataRendering src={this.state.things)>
      {(content) => (
        <ul>
          {content.map(thing => <li>{thing</li>})}
        </ul>
      )}
    </CustomRemoteDataRendering>
  }
}

With Vue

I have to make sure this actually works ;). But it should.

Example to render just the success:

<template>
  <div>
    <RemoteData>
      <ul slot-scope="props">
        <li v-for="thing in props.content">{{ thing }}</li>
      </ul>
    </RemoteData>
  </div>
</template>

<script>
export default {
  data() {
    return {
      things: new RemoteData('http://httpbin.org/get?data=a&data=b&data=c')
    }
  },

  mounted() {
    this.things.fetch()
  }
}
</script>

And to manage more things:

<template>
  <div>
    <RemoteData>
      <ul slot="ok" slot-scope="props">
        <li v-for="thing in props.content">{{ thing }}</li>
      </ul>

      <p slot="not-asked">
        <button @click="things.fetch()">Click here to load data</button>
      </p>

      <p slot="pending">
        loading...
      </p>

      <Warning slot="failed" slot-scope="props">
        Something did not worked as expected: {{ props.error.toString }}
      </Warning>
    </RemoteData>
  </div>
</template>

<script>
export default {
  data() {
    return {
      things: new RemoteData('http://httpbin.org/get?data=a&data=b&data=c')
    }
  },

  computed: {
    loadedThings() {
      return this.things.content || []
    }
  }
}
</script>

Same as in React, each slot is optional. So you could even use a RemoteData to model an ajax call that returns nothing, just to render on the loading and error state.

API

You can either pass a string to the RemoteData constructor, and that will be the url to fetch from. Or pass a callback.

// These 2 examples are equivalent:
const itIs = new RemoteData('http://httpbin.org.get')
const theSame = new RemoteData(() => axios.get('http://httpbin.org.get'))

RemoteData even use axios under the hood. But you can use anything as long as it returns a Promise. It does not have to be an http request.