• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

All About The Aurelia Fetch Client

Aurelia 1 · October 23, 2015

One source of confusion when working with AJAX requests and Aurelia is whether you should use the aurelia-http-client or aurelia-fetch-client both achieve similar things. However at the time of writing this no official documentation that exists for using the Fetch Client or explains how to use it.

I have been using the Fetch client since it debuted and realised others wanting to migrate to the Fetch client might find this post useful.

The Aurelia Fetch client is merely a thin wrapper around the native Fetch specification. So anything detailed in the Fetch specification can be achieved using the Aurelia Fetch client albeit the way the wrapper expects them to be done (which in most cases is the same as the spec).

Here are some basic things you might want to achieve using Aurelia Fetch client below like setting base URL’s, working with credentials, caching and more.

Polyfill alert: If you are planning on using Aurelia’s Fetch client you need to use a Fetch polyfill to plug browsers that do not support it that well. The Skeleton application uses Github’s Fetch API polyfill which is the best one out there at the moment.

Specifying a baseUrl

Before each request is made, the URL is prefixed with the supplied baseUrl.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        http.configure(config => {
            config
                .withBaseUrl('someBaseUrl/');
        });

        this.http = http;
    }

}

Working with credentials

Similar to XMLHttpRequest’s withCredentials property. Read more about the credentials property here.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        http.configure(config => {
            config
                .withDefaults({
                    credentials: 'same-origin' // Valid values; omit, same-origin and include
                });
        });

        this.http = http;
    }

}

Specifying custom headers

Using the same withDefaults method above, we can specify one or more custom senders to send with each request. Read more about the headers property here.

For every request

If you want some custom headers to be sent with every request, then using the withDefaults method does this for you.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        http.configure(config => {
            config
                .withDefaults({
                    headers: {
                        'Accept': 'application/json'
                    }
                });
        });

        this.http = http;
    }

}

Per request

Sometimes you want to send custom headers for a specific request, not every request like above. The code isn’t really that different. As you can see the fetch method has an optional parameter which allows us to provide an object of option values.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        this.http = http;
    }

    getSomeJson() {
        this.http.fetch('something', {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
                // More options
            }
        })
        .then(response => response.json())
        .then(data => {
            console.log(data);
        })
    }

}

Intercepting requests with interceptors

Pew, pew. Fire your lasers and intercept requests and response using the withInterceptor method.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        http.configure(config => {
            config
                .withInterceptor({
                    request(request) {
                        console.log(`Intercepted request using method: ${request.method} with URL: ${request.url}`);
                        return request;
                    },
                    response(response) {
                        console.log(`Intercepted response ${response.status} using URL: ${response.url}`);
                        return response;
                    }
                });
        });

        this.http = http;
    }

}

Requesting JSON

Probably the most common use-case is communicating with an API and expecting some sweet-sweet JSON to come back.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        this.http = http;
    }

    getSomeJson() {
        this.http.fetch('something')
            .then(response => response.json())
            .then(data => {
                    console.log(data);
            })
    }

}

Posting JSON

Sometimes you want to also give JSON, not just receive it. Your application might register a new user or create a page by sending a populated object to the server. Fetch with some Aurelia lovin’ has you covered here as well.

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

@inject(HttpClient)
export class MyClass {

    constructor(http) {
        this.http = http;
    }

    postSomeJson(user) {
        this.http.fetch('users', {
            method: 'post',
            body: json(user)
        })
    }

}

Conclusion

I probably forgot some things here. If there is something you think should be added here, something doesn’t work is not clear or you have a suggestion of your own, please leave a comment below.

Dwayne

Leave a Reply Cancel reply

18 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Steamonimo
Steamonimo
7 years ago

In my opinion the aurelia documentation is not sufficient for production ready code. Just deactivate the webserver and you will see that the “.then” promise will still be executed leading to other error messages of the aurelia framework.

I thought this can be handled by adding requestError(data) and responseError(data) to the config. Both of these functions are returning an empty json instead of throwing the data. But so far I did not have luck with this approach. Perhaps you have better ideas to properly handle communication errors? At least I want to alert the user and secondly I would like to execute other code than the “.then” promise.

0
Steamonimo
Steamonimo
7 years ago

I think I confused the handlers requestError and responseError for something that is better achieved with a catch handler:

.then(data => {…})
.catch(error => {…})

The only problem I now have is that the error object is always empty in my tests. Thus I find it difficult to inform the user with more details about the message. For that the statuscode and exception message of the fetch communication would be helpful.

0
James
James
7 years ago

Did anyone figure out how to catch the errors from the response?

0
Hector
Hector
7 years ago

It is possible to change the Content-Type when using json()? I want to send something like “Content-Type: ‘application/vnd.api+json'”, but json() by defaults set the Content-Type to “application/json” and it ignores the defaults headers and also the by request headers

0
Dwayne
Dwayne
Author
7 years ago

@James

I’ll be updating this post with a section on capturing errors shortly. There are definitely a couple of ways you can capture errors in your Fetch requests. Sadly, the documentation for Fetch is still limited, so I’ll try and make this post more comprehensive.

@Hector

Do you mean you want to change the content type of a GET or POST request? Like you want the content type changed when sending JSON to the server or getting it back?

0
Vladimir
Vladimir
7 years ago

Is there any way to pass request parameters?
For example aurelia-http-client has createRequest builder function, which gives helper function named withParams()

0
TIPS
TIPS
6 years ago

Some documentation on error handling for fetch requests would be greatly appreciated!

Thank you

0
Andrew
Andrew
6 years ago

It’s a shame that most of Aurelia’s best ‘documentation’ is still in the form of community blog posts like these. But kudos for the post, and I definitely second the request for more detail on properly handling errors. I would also really appreciate seeing how to implement a request timeout!

0
varun
varun
6 years ago

Could you specify more clearly with an example of how to connect to webapi and get data from it.I am new to webapi concept and I am not finding enough information in any site.

Thanks in advance.

0
mopawa
mopawa
6 years ago

@Andrew I’m quite new to Aurelia and specifically to its fetch client. What I have found is that if you want to catch errors returned through the header of the response (e.g. 401, 404 errors etc.), you can add an interceptor during the configuration of the client like this :

[code]
.withInterceptor({ response(response) { // MODIFY TO TAKE CAR OF OTHER 2XX SUCCESS CODES
if (response.status !== 200)
{
throw response;
}
else
{
return response;
}
}})
[/code]

Then when you make the request, add the “.catch” after all “.then” :

[code]
.catch(error => {
// Will log the http error status code
// Add any other actions here
console.log(error.status); });
[/code]

Hope this helps!

0
Rolex
Rolex
6 years ago

Great article.

0
C. daniel
C. daniel
6 years ago

Do you have a doc like this about the http-client?

0
James R.
James R.
6 years ago

Does the fetch client work for CORS POST requests? In my tests it only sends the OPTIONS post but not the following POST request. If I switch out code for jquery Ajax works fine.

0
jasc
jasc
6 years ago

Hi Dwayne, mayby you can help me?
During fetching data I’m getting error: Error:

A value is required for route parameter ‘id’ in route

The problem is because page is rendered before data are loaded and transformed by Aurelia to Promises:

this.client.fetch(‘/GetData’).then(response => response.json()).then(data => {
this.myData = data;
});
The only solution which is working for me is using if.bind=”itemFromMyData” in the repeat.for, but I don’t like because I’d like to force app to render page after all data transformations.

Do you have any idea?

0
larry
larry
6 years ago

What’s the difference with native fetch API, or what’s the benefits? Since I saw most of these features is implemented by fetch API.
I am using this, but want to know if I can switch to native fetch API without lose some important features.

0
Alex Rice
Alex Rice
6 years ago

Thanks for the article. One big unanswered for me though: How do you use responseError() and requestError() to detect, for example, when the web api is offline or unreachable?

0
William Felippe Ferreira da Silva
William Felippe Ferreira da Silva
6 years ago

There is a file (main.js maybe) where I can set the baseUrl for all my requests?
I’m starting in Aurelia, so sorry if is a stupid question.

0
Iain
Iain
5 years ago

Hi Dwayne, any chance of adding something on caching? I want to cache certain codes and lists, but if I manually cache the object then I open a memory leak.

How does the built-in cache work, and can I specify an expiration policy?

Thanks!

0

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Waiting for an Element to Exist With JavaScript
  • Thoughts on the Flipper Zero
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Paginate An Array In Javascript
  • How To Mock uuid In Jest
  • How to Copy Files Using the Copy Webpack Plugin (without copying the entire folder structure)
  • Reliably waiting for network responses in Playwright
  • Wild Natural Deodorant Review

Recent Comments

  • Dwayne on Is Asking Developers How to Write FizzBuzz Outdated?
  • kevmeister68 on Is Asking Developers How to Write FizzBuzz Outdated?
  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz