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: