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 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-supermodel

v1.4.7

Published

Supercharged REST-api wrapper for React.

Downloads

23

Readme

react-supermodel

Supercharged REST-api wrapper for React.

Features

  • Works out of the box
  • Backend-agnostic
  • Cache control
  • Optimistic/Pessimistic strategies for UI/data updating
  • Immutable state

Demo

  • Gif
  • https://codesandbox.io/s/04poy3y2kp

Installation

Through yarn

yarn add react-supermodel baobab

Through NPM

npm install react-supermodel baobab --save

Get started

1. Setup

The first thing you need to do is to init main config. Typically, your app's top-level component or main file like index.js will probably contains this config.

import { setConfig } from 'react-supermodel'
setConfig( options )

options.tree – required

Baobab instance. Make sure you have an $api cursor in your tree – it's required.

import Baobab from 'baobab'
import { setConfig } from 'react-supermodel'
const tree = new Baobab({
  $api: {}, //
  whateverYouNeedThere: {}, 
})
setConfig({ tree })

options.accept

Accept header for request. Default is json See – https://visionmedia.github.io/superagent/#setting-accept

options.auth

Authorization header. Default is empty string. Can be string or function. For example:

{
  auth: `Bearer: USER_TOKEN`,
  // Or using dynamic token
  auth: () => `Bearer: ${window.ComputeUserToken()}`,
}

options.prefix

Base URL prefix. Can be string or function. All model's requests will be prefixed with it. If you are going to use custom domain as prefix, make sure you know about CORS and credentials (see below).

setConfig({ prefix: '/api' })
// Or custom domain
setConfig({ prefix: 'http://customdomain.com/api' })
// Or custom function
setConfig({ prefix: () => `/api/${window.API_VERSION_CONFIG}` })

options.withCredentials

This option enables the ability to send cookies from the origin, however only when Access-Control-Allow-Origin is not a wildcard ("*"), and Access-Control-Allow-Credentials is "true". See – https://visionmedia.github.io/superagent/#cors

2. Create model

Once you've setuped supermodel's config, you'll need to create model. Basically model describes how to store/import/export and sync local data with an API provided data.

import { Model } from 'react-supermodel'
const UserModel = new Model({
  
  name: 'User', // This will be the name in props for connected component
  api: {
    get: '/users/:id', // :id will be replaced for real user is by connector
    list: '/users',
    create: 'POST /users',  // Also you can speciafy request's method with first-word prefix like GET, POST. DELETE, PUT
    delete: 'DELETE /users/:id',
    update: 'PUT /users/:id',
  }
})

modelOptions.name – required

name key contains the name of the model. It'll be passed to Component props via connect function.

modelOptions.idKey

idKey is the name for unique key of your objects. By default it is equal to id. For example, if your API has users collection contains an objects like {user_id: 1, user_name: 'admin'}, you should set up idKey as user_id.

modelOptions.dataItemKey

Default is data. Name of the key from your API response when requesting a single object.

modelOptions.dataListkey

Default is data. Name of the key from your API response when requesting a list.

modelOptions.api – required

The most important option. api is an object that describes how to work with your API. api has several predefined special keys which have a mapped dataflow methods like get, list, create, delete. You can also create your own methods. Working with connectors

Each property can be string contains an url pattern or an object. If you need to manipulate with response data, you should and object condiguration.

Here is an example how to add an extra property full_name to user object.

{
  api: {
    get: {
      url: '/user/:id', // the same if it was a string
      import( user ) {
        return {
          ...user,
          full_name: `${user.last_name} ${user.first_name}`
        }
      }
    }
  }
}

modelOptions.api.url

  • URL string.
  • Can be absolute starting with protocol (http://api2.mysite.com/api) or relative (/api), which will be prefixed with modelOptions.prefix prop.
  • Can be prefixed with method ("POST /api")
  • All urls can be interpolated with some data.

Examples:

  • If you call User.get( 1 ) with an url like /users/:id, Supermodel will interpolate it like /users/1.

  • If url will look like /users, Supermodel will interpolate it like /users?id=1

  • If url will look like POST /users Supermodel will send send POST request with JSON-payload like {id:1}. But if you need both (Request body and GET param), you should define an url like /POST /users?id=:id.

modelOptions.api.import

One of the most advanced feature. Basically it is simple data-processing function which describes how to import API data to storage. It is an entry point to convert or modify incoming data.

import( user ) {
  return {
    ...user,
    // Adding fullname property
    full_name: `${user.last_name} ${user.first_name}`,
    // Adding formatted birthdate string property from backend UNIX timestamp
    birthdate: moment(user.birth_timestamp * 1000).format('DD.MM.YYYY'),
  }
}

modelOptions.api.export

It is simple data-processing function which describes how to export your data to API. For example, user changed his birthdate:

export( user ) {
  return {
    // birth_timestamp is the name of propery stored on backend
    // So we should send it as UNIX timestamp
    birth_timestamp: moment(user.birthdate).unix() 
  }
}

modelOptions.optimistic

– WIP: UI/data updating strategy

3. Create connection

import connect from 'react-supermodel'
import UserModel from './models/UserModel'

@connect(UserModel)
class App extends Component {}

That's it.


Working with connectors

Once you've added connector to your component, you a ready to use it.

Getting connector

@connect(UserModel)
class App extends Component {
  render(){
    const { User } = this.props // Get UserModel's connector from props
    // ...
  }
}

Model's connector provides some predefined methods like get, list, create, delete, update and all using own dataflow inside.

.get( id )

Designed for using inside Component's render method.

const user = User.get(1)
return (<pre>{JSON.stringify(user)}</pre>)

Dataflow concepts

Examples

import connect from 'react-supermodel'
import UserModel from './models/UserModel'
@connect(UserModel)
class App extends Component {
  render(){
    // Get UserModel's connector from props
    const { User } = this.props
    // Getting users list from an API
    const users = User.list()
    // Showing progress indicator while users are loading
    if( users.isLoading ) {
      return 'Loading ...'
    }
    return (
      <ul>
        {users.data.map({data} =>
          <li key={data.id}>{data.name}</li>
        )}
      </ul>
    )
  }
}

Using Baobab as application's store

– WIP

Using with redux / etc

– WIP

Using without React

– WIP

Development & test

git clone https://github.com/ekorzun/react-supermodel.git
cd react-supermodel
yarn install
yarn test

Licence

MIT.