Skip to content

Instantly share code, notes, and snippets.

@StevenACoffman
Last active January 30, 2018 14:05
Show Gist options
  • Save StevenACoffman/3122621eceffa18fcb80c3249bef7bd5 to your computer and use it in GitHub Desktop.
Save StevenACoffman/3122621eceffa18fcb80c3249bef7bd5 to your computer and use it in GitHub Desktop.
Ajax (and RxJS)

Also might be worth checking out my other gist comparing react/redux async libraries.

This was interesting read on axios vs fetch api with regard to api error handling, XRSF, etc. In addition the specification doesn't have a way of dealing with timeouts or cancellation, so you need to do a fair amount of promise racing to do that. It's the standard, and they are working on it. See here and here.

rxjs ajax uses XmlHttpRequest

This comparison of Ajax libraries is interesting, so I added cancellation and timeout columns to it down below.

Support Features
Chrome & Firefox1 All Browsers Node Concise Syntax Promises Native2 Single Purpose3 Formal Specification Cancellable Timeout
XMLHttpRequest
Node HTTP
fetch()
Fetch polyfill
node-fetch
isomorphic-fetch
superagent
axios
request ?
jQuery
reqwest ? ?
  1. Chrome & Firefox are listed separately because they support fetch(): caniuse.com/fetch
  2. Native: Meaning you can just use it - no need to include a library.
  3. Single Purpose: Meaning this library or technology is ONLY used for AJAX / HTTP communication, nothing else.

When you create an Observable you can specify the unsubscribe behavior by returning a Subscription or a function from builder function:

fileUpload(file: File): Observable<any> {
    return new Observable( observer => {
        let xhr:XMLHttpRequest = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    observer.next(<any>JSON.parse(xhr.response));
                    observer.complete();
                } else {
                    observer.error(xhr.response);
                }
            }
        };

        xhr.open('POST', '__BACKEND__?action=file-upload', true);
        var formData = new FormData();
        formData.append('file', file, file.name);
        xhr.send(formData);

        //Return the tear down logic. 
        //You may also want to check here that it has not already completed
        //Since this gets called in all cases when the `Subscription` terminates
        return () => xhr.abort();
    });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment