Skip to content

Feature Request: Add support for providing a promise directly #4

@subodhpareek18

Description

@subodhpareek18

Instead of having to provide the url, headers, body, etc and then that be used in fetch, it would be great if given the user the option to simply provide a promise also which is called instead.

The use case arises when you build your own clients for your backend server and want to use those, since they already incoporate your custom setup of authentication, logging, error handling etc. And you might want to use your own http client or rest client. An infact might want to use your own websocket client. Making the api generic to handle any promise leads to a lot of possibilities.

Losing all the functionality by only giving the option to use fetch therefore is not ideal.

So I would propose this api change, and if it makes sense to you then I'd be happy to make a PR.

// Adding a new prop called promise which you can provide instead of url, headers, body, etc

const customPromise = backend.service('/database/users').get(userId)

<ReactPolling 
  promise={customPromise}
  interval= {3000} // in milliseconds(ms)
  retryCount={3} // this is optional
  onSuccess={() => console.log('handle success')}
  onFailure={() => console.log('handle failure')} // this is optional
  render={({ startPolling, stopPolling, isPolling }) => {
    if(isPolling) {
      return (
        <div> Hello I am polling</div>
          <Spinner />
        </div>
      );
    } else {
      return (
        <div> Hello I stopped polling</div>
        </div>
      );
    }
  }}
/>
// Inside the libary a one line change is made like so

runPolling() {
    const { url, interval, onSuccess, onFailure, api } = this.config;

    const _this = this;
    this.poll = setTimeout(() => {
      /* onSuccess would be handled by the user of service which would either return true or false
      * true - This means we need to continue polling
      * false - This means we need to stop polling
      */
      
      const promise = this.props.promise ? this.props.promise : () => fetch(url, api)

      promise()
        .then(resp => {
          return resp.json().then(data => {
            if (resp.ok) {
              return data;
            } else {
              return Promise.reject({ status: resp.status, data });
            }
          });
        })
        .then(onSuccess)
        .then(continuePolling => {
          _this.state.isPolling && continuePolling ? _this.runPolling() : _this.stopPolling();
        })
        .catch(error => {
          if (_this.config.shouldRetry && _this.config.retryCount > 0) {
            onFailure && onFailure(error);
            _this.config.retryCount--;
            _this.runPolling();
          } else {
            onFailure && onFailure(error);
            _this.stopPolling();
          }
        });
    }, interval);
  }

Thanks for all your work on this 🎉

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions