Skip to content

Instantly share code, notes, and snippets.

@bryanrsmith
Last active April 8, 2019 21:03
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bryanrsmith/14caed2015b9c54e70c3 to your computer and use it in GitHub Desktop.
Save bryanrsmith/14caed2015b9c54e70c3 to your computer and use it in GitHub Desktop.
aurelia-fetch-client documentation

An HTTP client based on the Fetch API. The project aims to embrace and expose the new Fetch API, while providing features important in web applications: default configuration of request parameters, interceptors, and centralized request tracking.

Bring Your Own Polyfill

This library relies on the Fetch API, which is not yet supported by all popular browsers. This library does not include a polyfill for Fetch. If you need to support browsers that haven't implemented Fetch, you will need to install a polyfill like GitHub's Fetch polyfill

import 'fetch';
import {HttpClient} from 'aurelia-fetch-client';

Basic Use

import {HttpClient} from 'aurelia-fetch-client';

let httpClient = new HttpClient();

httpClient.fetch('package.json')
	.then(response => response.json())
    .then(data => {
    	console.log(data.description);
    });

HttpClient.fetch() has the same signature as window.fetch(). The difference is that HttpClient will apply default configuration values, execute any registered interceptors, and track the number of active requests.

Configuration

httpClient.configure(config => {
	config
		.withBaseUrl('api/')
		.withDefaults({
			credentials: 'same-origin',
			headers: {
				'Accept': 'application/json',
				'X-Requested-With': 'Fetch'
			}
		})
		.withInterceptor({
			request(request) {
				console.log(`Requesting ${request.method} ${request.url}`);
				return request; // you can return a modified Request, or you can short-circuit the request by returning a Response
			},
			response(response) {
				console.log(`Received ${response.status} ${response.url}`);
				return response; // you can return a modified Response
			}
		});
});
  • The defaults object can include any properties described in the optional init parameter to the Request constructor, and will be merged into the new Request before it is passed to the first request interceptor.

  • Interceptors can be any object providing any of the four optional methods: request, requestError, response, and responseError.

    • request takes the Request that will be passed to window.fetch() after interceptors run. It should return the same Request, or create a new one. It can also return a Response to short-circuit the call to fetch() and complete the request immediately. Errors thrown in request interceptors will be handled by requestError interceptors.
    • requestError acts as a Promise rejection handler during Request creation and request interceptor execution. It will receive the rejection reason, and can either re-throw, or recover by returning a valid Request.
    • response will be run after fetch() completes, and will receive the resulting Response. As with request, it can either pass the Response along, return a modified response, or throw.
    • responseError is similar to requestError, and acts as a Promise rejection handler for response rejections.

Helpers

The Fetch API has a couple gotchas, documented by the GitHub Fetch polyfill docs. aurelia-fetch-client provides configuration helpers to apply the changes suggested by the polyfill docs.

  • config.rejectErrorResponses() will add a response interceptor that causes responses with unsuccessful status codes to result in a rejected Promise.

  • config.useStandardConfiguration() will apply rejectErrorResponses(), and also configure credentials: 'same-origin' as a default on all requests.

  • The Fetch API has no convenient way to sending JSON in the body of a request. Objects must be manually serialized to JSON, and the Content-Type header set appropriately. aurelia-fetch-client includes a helper called json for this.

import {HttpClient, json} from 'aurelia-fetch-client';
...
let comment = { title: 'Awesome!', content: 'This Fetch client is pretty rad.' };
httpClient.fetch('comments', {
	method: 'post',
	body: json(comment)
});

Limitations

  • This library does not include a polyfill for Fetch. If you need to support browsers that haven't implemented Fetch, you will need to install a polyfill like GitHub's Fetch polyfill.
  • This library does not work around any of the existing limitations in the Fetch API, including:
    • Fetch does not currently support aborting requests or specifying request timeouts.
    • Fetch does not currently support progress reporting.
  • JSONP support is not currently provided by this library.
  • The Request constructor provides its own default values, so if a Request is created before invoking HttpClient.fetch (eg, the HttpClient.fetch(request) signature is used instead of the HttpClient.fetch(url, params) signature), there is no way for the client to know which default values to merge into the Request. The base URL and headers can be merged, but currently no other defaults will be applied in this case.
@steamonimo
Copy link

In my opinion the example code for Configuration should demonstrate the use of requestError and responseError too. Both cases are important for code that is production ready. The same - again in my opinion - is true for the aurelia samples contact and skeleton. They too should demonstrate how communication errors are supposed to be handled. Showing an alert would be sufficient to built on top of that. Thanks, Holger.

@steamonimo
Copy link

I think I need to rephrase my previous post. Actually I confused reponseError, requestError to be used for communication errors. Now I have realized that .catch is used to handle errors in the communication of the fetch client. I think most users would like to get the error message and status code of the failed fetch attempt. So I still think the example under "Basic Use" should use .catch() after .then() to demonstrate accessing message and status code (403 etc) of the fetch exception.

@Nivl
Copy link

Nivl commented Nov 18, 2015

You are missing a return in the first then of Basic Use:

httpClient.fetch('package.json')
    .then(response => return response.json())
    .then(data => {
        console.log(data.description);
    });

@nevercast
Copy link

@Nivl

Arrow functions always return their result when used as an expression. Return is redundant.

Fn = (a) => "hello"
console.log(Fn())

Arrow Functions on MDN
You can test it on Babel also
Babel REPL

@httpJunkie
Copy link

Where are the docs for aurelia-http-client ?

@komenixx
Copy link

When use rejectErrorResponses() how can i parse response body to json in .catch() event ??

Parsed response looks like this:
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}

@kebin
Copy link

kebin commented May 22, 2016

To parse the actual server error message, you'd have to get the json first, which also returns a promise, which then would have the actual server error message. Something like the following:
.catch(error => error.json() .then(serverError => { this.addError = serverError.something }));

@komenixx
Copy link

komenixx commented May 26, 2016

Fixed with interceptor:

return response.json().then(Promise.reject.bind(Promise));

@kdekooter
Copy link

How to add url query parameters when using the GET method?

@afm-sayem
Copy link

@kdekooter aurelia-path module has a method called buildQueryString which builds a query string from an object. I'm using that to build the query string and then append that query string to the request.

@nampord
Copy link

nampord commented Oct 7, 2016

I am trying to issue a cross-origin request with the credentials, so I set credentials: 'include' in the configuration, but it seems that the credentials are not send. Is CORS with credentials supported ?

@younesouhbi
Copy link

What @nampord said. I've been trying to send a cross-origin request having both mode: 'cors' as well as credentials: 'include'. It seems that 'include' isn't supported. Can anyone confirm this? And if it's the case, is there a workaround?
Thanks!

@pbgc
Copy link

pbgc commented Apr 8, 2019

This library does not work around any of the existing limitations in the Fetch API, including:

Fetch does not currently support aborting requests

This is not true anymore ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment