Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
aurelia-fetch-client documentation

aurelia-fetch-client

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

This comment has been minimized.

Copy link

@steamonimo steamonimo commented Nov 16, 2015

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

This comment has been minimized.

Copy link

@steamonimo steamonimo commented Nov 17, 2015

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

This comment has been minimized.

Copy link

@Nivl 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

This comment has been minimized.

Copy link

@nevercast nevercast commented Nov 30, 2015

@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

This comment has been minimized.

Copy link

@httpJunkie httpJunkie commented Apr 29, 2016

Where are the docs for aurelia-http-client ?

@komenixx

This comment has been minimized.

Copy link

@komenixx komenixx commented May 20, 2016

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

This comment has been minimized.

Copy link

@kebin 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

This comment has been minimized.

Copy link

@komenixx komenixx commented May 26, 2016

Fixed with interceptor:

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

@kdekooter

This comment has been minimized.

Copy link

@kdekooter kdekooter commented Sep 16, 2016

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

@afm-sayem

This comment has been minimized.

Copy link

@afm-sayem afm-sayem commented Sep 18, 2016

@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

This comment has been minimized.

Copy link

@nampord 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

This comment has been minimized.

Copy link

@younesouhbi younesouhbi commented Mar 1, 2017

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

This comment has been minimized.

Copy link

@pbgc 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