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-ferry

v0.1.1

Published

JSON API developed originally for BC-CfE's QAI System

Downloads

5

Readme

react-ferry

GitHub license

React Ferry is a collection of utilities for connecting React interfaces to a RESTful API.

While not necessary, it also works well with React Router.

JsonApi

  • Respects the Location header
  • Handles error responses. Expects errors in the format {"error": "[error message]"}, but degrades gracefully if a non-JSON response (e.g. a plain string) is received.
  • [optional] Use the routeWith parameter to enable server redirects. In this mode, server messages and errors are stored in history's invisible state object.

Basic usage:

JsonApi.get('/rest-resource/101', {parameter: 'value'}).then(resp => {
    // response is interpreted as JSON
    callback(response);
}).catch(error => {
    errorCallback(error);
});

JsonApi handles HTTP requests, including GET, POST, PATCH, PUT, DELETE, LINK, and UNLINK.

JsonApi.get
JsonApi.post
JsonApi.put
JsonApi.patch
JsonApi.delete
JsonApi.link
JsonApi.unlink

GET requests will have their parameters URL-encoded and appended to the endpoint. All other requests will have their parameters sent as JSON in the request body.

Provide a history handle if you want the HTTP Location header to be followed. Since you may be navigated away from the current page, the server response will be recorded in history.state with the key serverMessage. If an error occurs, it will be recorded with the key errorMessage.

import {createBrowserHistory} from 'history';
let history = createBrowserHistory();
JsonApi.get('/rest-resource/101', {}, {routeWith: history});

You may cancel an API request before it finishes.

let handle = JsonApi.get('/rest-resource/101');
handle.cancel();
// JsonApi request is halted

For debugging purposes, you can enable logging.

import {enableLogging, disableLogging} from 'react-ferry/json-api'

enableLogging(); // send debugging messages to console.log
disableLogging(); // cancel debugging messages

function customLogger(message) {
    window.alert(message);
}
enableLogging(customLogger); // send debugging messages to customLogger 

LoaderHOC

LoaderHOC is a React higher-order-component for fetching an HTTP resource and displaying it to the user. All you need are the resource URL and the React display component.

Basic usage

let ComponentLoader = LoaderHOC<ResultType>(url)(Component);
<ComponentLoader id={id} />
 => <Component id={id} data=[...] />

You may provide your own error display.

let ComponentLoader = LoaderHOC<ResultType>(url, {
    renderError(message) {
        return <MyMessageComponent>{ message }</MyMessageComponent>
    }
})(Component);

<ComponentLoader id={id} /> // server returns error or empty set
 => <MyMessageComponent>Server Error</MyMessageComponent>

You may provide your own custom loading indicator.

let ComponentLoader = LoaderHOC<ResultType>(url, {
    renderLoader() {
        return <MySpinnyWheel/>
    }
})(Component);

<ComponentLoader id={id} />  
 => <MySpinnyWheel/> // while waiting for server response

An empty array response will result in an error message.

Passing props through the loader

let ComponentLoader = LoaderHOC<ResultType, { passedThru: any }>(url)(Component);
<ComponentLoader id={id} passedThru={{ foo: 'bar' }} />
 => <Component id={id} data=[...] passedThru={{ foo: 'bar' }} />

Setting API request parameters

let ComponentLoader = LoaderHOC<ResultType, {}, { id: number, apiFlag: boolean }>(url)(Component)
<ComponentLoader apiQuery={{ id: 1, apiFlag: true }} />
 => <Component id={1} apiFlag={true} />

Custom API parameter computation

let ComponentLoader = LoaderHOC<ResultType, { passedThru: string }>(
    url,
    { 
        getApiQuery(props) {
            return { query: props.passedThru }
        }
    }
)(Component)

<ComponentLoader passedThru="value" />
 => <Component query="value" passedThru="value" />

Post-processing of data

let ComponentLoader = LoaderHOC<ResultType>(
    url,
    { 
        serverAdapter(data) {
            return Object.assign({}, data, { addedProp: `value of foo: ${data.foo}` })
        }
    }
)(Component)

<ComponentLoader id={id} />
 => <Component id={id} data=[...] addedProp="value of foo: bar" />

Usage with React-Router

let RouteLoader = LoaderHOC<ResultType, RouteComponentProps<RouteParams>>(
    url,
    {
        getApiQuery(props) {
            return ({ id: props.match.params.id });
        }
    }
)(Component)

<Route path={pathName + '/:id'} component={RouteLoader}/>
 => <Component match={...} history={...} location={...} id={id} data=[...] />
 

Set application-wide settings using configureDefaults

import {configureDefaults} from 'react-ferry/loader-hoc'

// Set a global data postprocessor:
configureDefaults({ 
    serverAdapter(data) {
        return { dataWrapper: data };
    } 
});

// Set a global display for error messages:
configureDefaults({ 
    renderError(message) {
        return <MyMessageComponent>{ message }</MyMessageComponent>;
    } 
});

// Set a global loading indicator:
configureDefaults({ 
    renderLoader() {
        return <MySpinnyWheel/>;
    } 
}); 

Modifying the record

By its nature, a Loader component only performs GET requests. However, the resulting component may make alterations to the model on the server. In this case, any time a model is altered, the component should call a special prop called onServerChange. The loader will then reload the data.

onError

Sometimes you will need to know if the server returned an error. In this case, provide a callback.

<ComponentLoader onError={errorMessage => doSomething(errorMessage)} />

LoaderHOC will display the error using its renderer. To suppress this, explicitly return false from the callback.

<ComponentLoader onError={errorMessage => {
    doSomething(errorMessage);
    return false;
}} />

@todo

Documentation for ComposerHOC upcoming. In the meantime, comments in the source files may be of help.