On Github hongkheng / intro-to-fetch-talk-slides
By Yap Hong Kheng / @hongkheng
var xhr = new XmlHttpRequest(); xhr.open('GET', './some-api/some.json', true); xhr.onload = function() { if(xhr.status >== 200 && xhr.status <== 301 ) { var data = JSON.parse(xhr.responseText); console.log(data); } }; xhr.onerror = function(err) { console.log('Cannot fetch data', err); }; xhr.send();
Replacement for XmlHttpRequest (xhr)
Aim to be more powerful and flexible than XHR
Lower level than XHR
es6
Promise
Use with Service Worker
// Basic example, by default is a 'GET' request fetch('url') .then(function(response) { // returns a Response object which is a Promise });
Different ways to initialize fetch
// more common syntax fetch('url', { method: 'PUT', headers: { 'Content-Type': 'application/json' } }).then(function(response){ // do something with response });
fetch() uses browser native Promise
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
var p1 = new Promise(function(resolve, reject){ // do something var response = { some: 'data'}; // Fulfilled with a value resolve(response); }); p1.then(function(response) { console.log('Fulfilled', response); }).catch(function(reason){ // rejected console.log('Error', reason); });
fetch('./some-api/some.json') .then(function(response){ if (response.status >== 200 && response.status < 300) { return response.json(); } else { var error = new Error(response.statusText); error.response = response; throw error; } }).catch(function(error){ console.log(error); });
fetch('./some-api/some.json') .then(response => { if (response.status >== 200 && response.status < 300) { return response.json(); } else { var error = new Error(response.statusText); error.response = response; throw error; } }).catch(error => { console.log(error); });
examples later on will be in es6
In normal XHR headers it willl look like:
... var basicAuth = 'Basic ' + btoa(username + ':' + password); xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.setRequestHeader('Authorization', basicAuth); ...
In fetch(), you can pass headers like this. e.g an POST method
let authHeader = 'Basic ' + btoa(username + ':' + password); fetch(url, { method: 'POST', credentials: 'include', headers: { 'Authorization': authHeader, 'Content-Type': 'application/json;charset=UTF-8' } }).then(response => { return response.json(); }); // highlight the headers objects
You can also define in a variable form
var headers = new Headers(); headers.append(Content-Type','application/json;charset=UTF-8'); ... // define back in fetch fetch(url, { method: 'POST', headers: headers ... });
Query the type of Headers return by the Response
fetch('url').then(response => { // determine the how to parse the response type // via the headers if(response.headers.get('Content-Type') === 'application/json; charset=UTF-8') { return response.json(); } else { return response.text(); } }).then(data => data) .catch(error => error);
More on Headers
Create a new Request object to initialize fetch().
Read-only object
// Note: the url will try to find your root domain url. var request = new Request('someimage.png'); var url = request.url; // http://yourdomain/someimage.png fetch(request).then(response => response); // OR var request = new Request('someimage.png', { method: 'GET' }); fetch(request).then(response => response);
// from MDN self.addEventListener('fetch', function(event) { console.log('Handling fetch event for', event.request.url); event.respondWith( caches.match(event.request).then(function(response) { if (response) { console.log('Found response in cache:', response); return response; } console.log('No response found in cache. About to fetch from network...'); return fetch(event.request).then(function(response) { console.log('Response from network is:', response); return response; }).catch(function(error) { console.error('Fetching failed:', error); throw error; }); }) ); });
More on Request
Let's look at the response object and see what it returns
http://jsbin.com/yolivap/edit?html,js,outputMore on Response
Mixin that is implemented by Response & Request
Can be FormData, JSON, string, blob, ArrayBuffer
// Passing a JSON data fetch('url', { method: 'PUT', headers: { 'Content-Type': 'application/json;charset=UTF-8' }, body: JSON.stringify({ some: 'data'}) });
fetch('url') .then(response => response.json()) .then(data => data); // -- this is a parsed JSON data! //same for plain text ... return response.text(); // or status message ... return response.statusText();
More on Body
Caveat: HTTP error status would not be rejected. It is still consider a valid response.
Solution: Check for valid response.status or response.ok Throw error when it is not valid and do a catch().
fetch('./some-api/some.json') .then(response => { // Check for status codes if (response.status >== 200 && response.status < 300) { return response.json(); } else { var error = new Error(response.statusText); error.response = response; throw error; } }).catch(error => { console.log(error); });
Use fetch with Spotify API
It isn't finish... so...
polyfill: github/fetch
https://github.com/whatwg/streams
http://blogs.igalia.com/xrcalvar/2015/07/23/readablestream-almost-ready/
Slides: http://hongkheng.github.io/intro-to-fetch-talk-slides/
References: