Giter Club home page Giter Club logo

react-fetch-component's People

Contributors

aaronjensen avatar davin-english-tfs avatar flamenaak avatar lediur avatar rodolfosilva avatar techniq avatar tiodan81 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

react-fetch-component's Issues

Supply caching strategy

Currently we have a single cache prop as a bool that uses an object to store the {url: Promise} for each request if enabled and checks if an entry exists (see here)

If would be nice if you could pass in your own cache instance to support:

I think it should be as simple as supporting passing an object to cache that has a get and set function that returns Promises (need to support multiple in-flight requests waiting on the same request).

class SimpleCache {
  get(url) {
    // load from internal object, read from local storage, etc
  }

  set(url, result) {
    // set to internal object, set to local storage, etc
  }
}

const myCache = new SimpleCache()

<Fetch cache={myCache} />

If you wanted to clear the cache, you would do that on your own cache instance (if provided), such as:
myCache.clear()

`loading` initially starts as `null`?

Maybe I'm doing something wrong, but this seems weird to me. Here's my code:

<Fetch url="/in-progress">
    {({loading, error, data}) => {
        console.log(loading,error,data);
        if(!data) {
            return <p>Loading...</p>
        }
    }}
</Fetch>

And the output:

image

Loading is null on the first invocation. Why is that? I would think it'd start as true. this prevents me from doing if(loading) for my condition!

Uncaught (in promise) TypeError: failed to fetch

Fatal fetch errors are not caught and passed as props to the render callback.

To reproduce, make a fetch to any URL that does not support CORS (i.e. https://example.org). This will immediately fail to fetch the URL because the server does not respond with a Access-Control-Allow-Origin header.

Because the error occurs before the request is made, a response is never created. This causes the existing error handler to never run and thus allows errors to go uncaught.

This can be easily remedied by adding a catch clause to the Promise to catch any error and handle it appropriately through your error handler:

.catch((error) => {
  const newState = {
    data: undefined,
    error,
    loading: false
  }
  this.setStateIfMounted(newState)
  return newState
});

How to refetch data if error occured

Hey!
I have a case where when the error while fetching occurs, I would give the user ability to try again using a button.
Would be nice to have the instance of current component, because I use the same functions for multiple components.

Regards,
TheAifam5.

Add explicit "onDataChange" property

Currently we overload onChange and if it does not return undefined, we replace the data with the result of onChange. This is error prone (dispatching redux functions in onChange, not handling reloading states properly, etc).

Instead it would be better if we have an explicit onDataChange handler that is only called when data is returned (before here and only when data is changed)

Questions to think about

  • Should we call it onDataChange or processData
  • If called onDataChange, is it obvious it is called before onChange and will modify data handed to it
  • onDataChange could simplify uses of onChange. Example: onChange={({data}) => data && dispatch(someAction(data)) onDataChange(data => dispatch(someAction(data))

Only retain successful responses in cache

Hi @techniq,

I saw you had a TODO on SimpleCache: // TODO: only retain successful responses?

Not sure how high this is on your priority list, but it would be a great help for my use-case (and I'm sure others). If there's a brief network error when making a fetch call, the URL gets set in the cache even though it errored. As such, subsequent calls are never made.

I'm currently working around this by removing the URL from the cache in the error callback, but it would be nice if the lib handled it for me (even if it's a prop on the Fetch component itself so users aren't forced into not caching unsuccessful calls). Having the lib handle it would remove a fair amount of boilerplate code where I'm doing the same workaround.

Smart body parsing based on Content-Type

Instead of defaulting to json for body parsing, it would be better if we read the response's Content-Type header and parsed accordingly. This would also better handle when the endpoint changes types (ex. some frameworks will return a HTML debug page when a 500 is thrown, which breaks when we expect an endpoint to return JSON).

After a quick look around, it appears fetch-parse has a good start on the mapping between Content-Type and parsers.

Probably look at using one of the following to parse the header / mime type, as it can be fairly involved to cover all cases defined by the spec.

Lastly, it would be nice to support passing a function to as to allow the user to perform the body parsing mapping themselves (might be needed to determine whether they need blob or arrayBuffer.

Support aborting

Now that fetch supports aborting using AbortController via a signal, it would be nice if we did as well. Currently we track whether the component is mounted and not call setState, but properly cancelling the fetch request would be better, especially since it's considered an anti-pattern

Some details:

It's only supported in recent green browsers (Chrome, Firefox, Edge, Safari (desktop) and not IE, iOS Safari (currently) so we will need to support opting in / polyfiling.

A quick search returned this polyfill, and Netflix's yetch (which you should be able to pass to the fetchFunction prop

Maybe this is an opt-in via cancellable prop, and we continue to track mounted otherwise.

error remains an empty object

I purposefully sent incorrect cors-mode to a url.

Fetch API cannot load https://swapi.co/api/films/. Request mode is "same-origin" but the URL's origin is not same as the request origin http://localhost:7331.

prints to my console but error as a renderProp remains {}

Allow for fetching cached data

Hi! Thanks so much for your work on this package; overall I really like the API!

I was wondering if there's any way to allow for fetching data on mount/update even when that data has been cached? I know that seems to go against the purpose of a cache, but I'd like to optimistically show data that's already been loaded and doesn't change often (and possibly been cached for a longer period of time, like in localStorage/sessionStorage) but still fetch in case any changes have happened. This is for an enterprise application which receives fairly low traffic, so I don't need caching for load reasons.

From my reading of the fetch method, it looks like this isn't something I could do with a custom Cache =/

Add support for Hooks

Support useFetch hooks API

function Example(props) {
  const { loading, data, error } = useFetch({ url: props.url });
  // ...
}

along with the existing Fetch render props component

function Example(props) {
  <Fetch url={props.url}>
    {({ loading, data, error }) => (
      // ...
    )}
  </Fetch>
}

To support consistency with the Fetch component, the useFetch hook will take in a props object for url, options, etc.

I might consider change the name of the package to better represent it's not just a component (but also a hook). I'm considering using a scoped @techniq/react-fetch instead of trying to come up with a unique name.

TODO

  • Update README
  • Switch to Typescript
  • Wait for official React release with hooks

Support async onDataChange

It would be very useful if you could return a Promise from onDataChange to allow using asynchronous APIs (callbacks/promises) within it. For example you could process some blob data using FileReader (untested example, but general idea);

<Fetch
  url="/someFile"
  as="blob"
  manual
  onDataChange={data => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = e => resolve(e.target.result);
      reader.readAsDataURL(data);
    });
  }}
>
  {({ data: dataUrl, fetch }) => (
    data ? (
      <iframe src={dataUrl} />
    ) : (
      <a onClick={() => fetch()}>Download</a>
    )
  )
</Fetch>

or if onDataChange could be async

async function getDataUrl(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = e => resolve(e.target.result);
    reader.readAsDataURL(data);
  });
}

<Fetch
  url="/someFile"
  as="blob"
  manual
  onDataChange={async data => {
    const dataUrl = await getDataUrl(data);
    return dataUrl;
  }}
>
  {({ data: dataUrl, fetch }) => (
    data ? (
      <iframe src={dataUrl} />
    ) : (
      <a onClick={() => fetch()}>Download</a>
    )
  )
</Fetch>

Support refetching if `options.body` changes, even if url doesn't

In the version that I'm using,

if (url && url !== prevProps.url && !manual) {
specifies that we shouldn't refetch if the url hasn't changed.

In my code I'm using this component with a POST call with a body, where the user can modify the page state to change the body, which I'd like to trigger a refetch, but since the URL is the same, it doesn't. I worked around this by adding a fragment to the end of the URL that takes a hash of the body, but it'd be nice if this just worked by default. At minimum, it would be good if this behavior was documented, since I had to spend a decent amount of time poking around before I figured it out.

Is this project abandoned?

Was curious if api could be extended, with things like skip, fetchMore, refetch which are implemented in react-apollo/Query

Support Suspense

Will need to wait for react-cache to be officially released (which is currently slated for mid 2019).

An implementation is available that rolled it's own caching (https://github.com/CharlesStover/fetch-suspense), although this is likely not production ready (cache invalidation, etc)

Mostly creating this as a feature tracking issue for now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.