grab-http

0.1.4 • Public • Published

grab

A promisified XMLHttpRequest with an API close to fetch.

Install

npm install grab-http --save

Requirements

The Promise API. You can use any polyfill you want, just be sure it's present inside the window / global object. Browser support is now pretty good (except IE).

For very old browsers, consider including a ES5 shim for methods like Object.keys.

Dependencies

Features

  • support old browsers
  • onProgress listener
  • timeout
  • cancel

Usage

import grab from 'grab-http';

// GET /api/users?limit=10
grab('/api/users', { params: { limit: 10 }}).then(response => {
  console.log(response.json());
}).catch(error => {
  console.error(error);
});

// POST /api/users
grab({method: 'POST', url: '/api/users', body: { name: 'Paul' }})
  .then(response => console.log('User created'))
  .catch(error => console.error(error));

FAQ

  • What's the point? There is the fetch API now. That's true, and if that's fine with you, use it. But right now, fetch has too many limitations for some projects, like no progress nor abort like XMLHttpRequest.

  • Is it the same API as fetch? Can I use it as a polyfill? Not at all. It's quite close but not the same. For example, cache is just a boolean and not a string. All methods reading the response body are synchronous since there is no way to handle a XMLHttpRequest response asynchronously. Refer to the API below for the full documentation.

API

grab(input, options)

Parameters

  • input: either a string matching a valid url or an object used as the options parameter.
  • options: object containing the request configuration
    • url (required if no string input): a string containing the direct URL of the resource you want to grab.
    • method (default: 'GET'): the request method, e.g., GET, POST.
    • body (any): the body of the request. If JavaScript object, will be stringified and Content-Type: application/json header will be added
    • params (object): a map of key/value which will be added to the query string
    • headers (object): a map of key/value for all the request headers
    • timeout (number): the number of milliseconds before stopping the request, rejecting it with a TimeoutError.
    • cancel (Promise): when this promise is resolved, it will stop the request, rejecting it with a CancelError.
    • credentials (boolean): flag for xhr.withCredentials
    • responseType (string): assigned to xhr.responseType
    • onProgress (function): a function called by the XMLHttpRequest with a progress event.
    • urlEncoded (boolean): if true, body objects will be serialized as form url encoded and Content-Type: application/x-www-form-urlencoded will be added.
    • username (string): optional user name to use for authentication purposes.
    • password (string): optional password to use for authentication purposes.

Returns

A promise that will eventually be resolved with a Response object. This promise has a bonus method cancel that will abort the XMLHttpRequest if called. This method is not transitive, if you chain the promise, you will lose it.

Response

Attributes

  • type: contains the type of the response . Always 'default' right now
  • status: contains the status code of the response (e.g., 200 for a success).
  • statusText: contains the status message corresponding to the status code (e.g., OK for 200).
  • ok: contains a boolean stating whether the response was successful (status in the range 200-299) or not.
  • headers: contains all headers associated with the response as a map object of key/value.
  • body: contains the raw body of the response.

Methods

  • text(): return the raw body as string.
  • json(): return the body as a JavaScript object (using JSON.parse).
  • formData(): return the body as a FormData instance if possible.

Defaults

You can override or add any default parameter using grab.defaults.

  • method (string): GET
  • log (function): empty. See logging section.
  • timeout (number): 0
  • headers (object): {}
  • cache (boolean): false in most case except for some IE.
  • base (string): ''
  • credentials (boolean): false
  • FormData (object): window.FormData in the browser and undefined in Node.You can assign any implementation you want if you need to use FormData inside Node. You can also override the browser default if needed.
// Set a timeout to all requests
grab.defaults.timeout = 60000;

// Add a custom header to all requests
grab.defaults.headers['X-Custom-Header'] = 'CustomValue';

Any parameter inside options when calling grab will override the defaults. For example, you can put a timeout for all your requests by default but disable it for a particular long request by setting timeout: 0 inside the options. Objects will also be overridden and not merged. Feel free to add any other default you need, they will be copied inside the options if possible. For example, you can do grab.defaults.urlEncoded = true; to make all your requests form url encoded by default.

Shortcuts

There is a shortcut for every HTTP methods, the syntax is grab.[METHOD](url, [body], options). POST, PUT and PATCH supports a body parameter, all others don't.

grab.get('/users');
grab.post('/users', { id: 1, name: 'Paul', admin: true });
grab.put('/users/1', { name: 'Alex', admin: false });
grab.patch('/users/1', { admin: true })
grab.delete('/users/1');

Methods

grab.serialize

Parameters

A JavaScript object of key / value parameters.

Returns

A valid url query string.

grab.serialize({page: 2, limit: 20});
// returns 'page=2&limit=20'

grab.resetDefaults

Parameters

None

Returns

Reset all defaults to their initial value and return it.

Logging

You can enable logs by providing a grab.defaults.log function. It takes only one parameter which has the following attributes:

  • ok (boolean): true if it's just an info, false if something went wrong.
  • message (string): what just happened.
grab.defaults.log = function (out) {
  if (out.ok) {
    console.log(out.message);
  } else {
    console.error(out.message);
  }
};

Errors

Depending on your parameters or the network response, the following errors can be triggered.

  • TypeError: probably something wrong with your parameters.
  • NetworkError: the XMLHttpRequest has failed.
  • TimeoutError: the request has reached its timeout.
  • CancelError: you have manually canceled the request.
  • AbortError: the XMLHttpRequest has been aborted but we don't really know why. Both TimeoutError and CancelError extend this error.
import grab from 'grab-http';
import { TimeoutError, CancelError } from 'grab-http';

grab('/api/users', { timeout: 10 })
  .then(response=> {
    console.log('All users', response.json());
  })
  .catch(error=> {
    if (error instanceof TimeoutError) {
      console.warn('Couldn\'t make it in time...');
    } else if (error instanceof CancelError) {
      console.warn('Who canceled the request?!');
    } else {
      console.error(error);
    }
  });

You can also use error codes from grab.errors, you have network, timeout, cancel and abort.

import grab from 'grab-http';

grab('/api/users', { timeout: 10 })
  .then(response=> {
    console.log('All users', response.json());
  })
  .catch(error=> {
    if (error.code === grab.errors.timeout) {
      console.warn('Couldn\'t make it in time...');
    } else if (error.code === grab.errors.cancel) {
      console.warn('Who canceled the request?!');
    } else {
      console.error(error);
    }
  });

Tests

First start the dev server using npm start and then run the tests with npm test.

Thanks

Thanks a lot to @gre for all the inspiration from qajax.

License

This software is licensed under the Apache 2 license, quoted below.

Copyright 2015 Paul Dijou (http://pauldijou.fr).

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Package Sidebar

Install

npm i grab-http

Weekly Downloads

0

Version

0.1.4

License

Apache-2.0

Last publish

Collaborators

  • pauldijou