Skip to content

Commit

Permalink
Merge branch 'vivek12345-feature-replace-jquery-with-fetch'
Browse files Browse the repository at this point in the history
  • Loading branch information
typicode committed Nov 8, 2017
2 parents 8dc47be + cbe9d95 commit 2a0183b
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 111 deletions.
176 changes: 115 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ I hope you will find it useful.
* Basic API
* "Has many" relationships
* Filters and nested resources
* Cross-domain ([CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) and [JSONP](http://en.wikipedia.org/wiki/JSONP))
* Cross-domain ([CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)) and [JSONP](http://en.wikipedia.org/wiki/JSONP))
* Supports GET, POST, PUT, PATCH, DELETE and OPTIONS verbs
* Compatible with Backbone, AngularJS, Ember, ...
* Compatible with React, Angular, Vue, Ember, ...

## Available resources

Expand All @@ -46,43 +46,79 @@ Let's start with resources, JSONPlaceholder provides the usual suspects:

## How to

Here's some code using jQuery showing what can be done with JSONPlaceholder.
Since GitHub loads jQuery, you can simply copy and paste these examples in a console.
Here's some code using fetch api (which is now supported by all major browsers) showing what can be done with JSONPlaceholder.

You can read more about how fetch works using the following links: https://developers.google.com/web/updates/2015/03/introduction-to-fetch

* If you are working with a JSON API, you'll need to check the status and parse the JSON for each response.
* You can simplify your code by defining the status and JSON parsing in separate functions which return promises, freeing you to only worry about handling the final data and the error case.

### Common Code for all fetch calls
```javascript
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}

function json(response) {
return response.json()
}
```

### Showing a resource

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1', {
method: 'GET'
}).then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(status)
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});
```
Note: The response of a fetch() request is a Stream object, which means that when we call the json() method, a Promise is returned since the reading of the stream will happen asynchronously.

### Listing resources

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts', {
method: 'GET'
}).then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts')
.then(status)
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});
```

### Creating a resource

```javascript
// POST adds a random id to the object sent
$.ajax('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
data: {
title: 'foo',
body: 'bar',
userId: 1
}
}).then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});

/* will return
{
Expand All @@ -99,17 +135,25 @@ Note: the resource will not be really created on the server but it will be faked
### Updating a resource

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PUT',
data: {
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}
}).then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PUT',
body: JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});

/* will return
{
Expand All @@ -122,14 +166,22 @@ $.ajax('https://jsonplaceholder.typicode.com/posts/1', {
```

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PATCH',
data: {
title: 'foo'
}
}).then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PATCH',
body: JSON.stringify({
title: 'foo'
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});

/* will return
{
Expand All @@ -146,7 +198,7 @@ Note: the resource will not be really updated on the server but it will be faked
### Deleting a resource

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1', {
fetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'DELETE'
});
```
Expand All @@ -159,20 +211,32 @@ Basic filtering is supported through query parameters.

```javascript
// Will return all the posts that belong to the first user
$.ajax('https://jsonplaceholder.typicode.com/posts?userId=1').then(function(data) {
console.log(data);
});
fetch('https://jsonplaceholder.typicode.com/posts?userId=1')
.then(status)
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});
```

### Nested resources

One level of nested route is available.

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1/comments').then(function(data) {
console.log(data);
});
// Which is equivalent to /comments?postId=1
// equivalent to /comments?postId=1
fetch('https://jsonplaceholder.typicode.com/posts/1/comments')
.then(status)
.then(json)
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch Error :-S', error);
});
```

Here's the list of available nested routes:
Expand All @@ -182,13 +246,3 @@ Here's the list of available nested routes:
* https://jsonplaceholder.typicode.com/users/1/albums
* https://jsonplaceholder.typicode.com/users/1/todos
* https://jsonplaceholder.typicode.com/users/1/posts

### JSONP request

```javascript
$.ajax('https://jsonplaceholder.typicode.com/posts/1', {
dataType: 'jsonp'
}).then(function(data) {
console.log(data);
});
```
105 changes: 55 additions & 50 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,9 @@ <h2>Example</h2>

<pre><code id="example" class="javascript">var root = 'https://jsonplaceholder.typicode.com';

$.ajax({
url: root + '/posts/1',
method: 'GET'
}).then(function(data) {
console.log(data);
});</code></pre>
fetch(root + '/posts/1')
.then(data => console.log(data.response()));
</code></pre>

<p>
<button id="run">Run</button>
Expand Down Expand Up @@ -254,26 +251,23 @@ <h2>Use your OWN data</h2>
</p>
</a>
-->

<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

ga('create', 'UA-44497010-1', 'typicode.com');
ga('send', 'pageview');

var trackOutboundLink = function (url) {
}, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a,
m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); ga('create', 'UA-44497010-1', 'typicode.com');
ga('send', 'pageview'); var trackOutboundLink = function (url) {
ga('send', 'event', 'outbound', 'click', url, {
'transport': 'beacon'
'transport':
'beacon'
});
}
</script>

<script>window.twttr = (function (d, s, id) {
<script>
window.twttr = (function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
Expand All @@ -288,41 +282,52 @@ <h2>Use your OWN data</h2>
};

return t;
}(document, "script", "twitter-wjs"));</script>
}(document, "script", "twitter-wjs"));
</script>

<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script>
// Use http or https based on location.protocol
var exampleText = $('#example').text()
$('#example').text(exampleText.replace('http:', location.protocol))

// Highlight result element
$('#result').each(function (i, block) {
hljs.highlightBlock(block);
});

// Run example
$('#run').click(function () {
var root = location.protocol + '//jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/1',
method: 'GET'
}).then(function (data) {
var str = JSON.stringify(data, null, '\t')
$('#result').html(
str.replace(/\n/g, '<br/>')
.replace(/\\n/g, ' ')
.replace(/\t/g, '&nbsp;&nbsp;')
);

$('#result').each(function (i, block) {
hljs.highlightBlock(block);
});
});
});

// Tell that jQuery can be used in console
console.log('You can use jQuery functions')
// Use http or https based on location.protocol
var exampleText = $('#example').text()
$('#example').text(exampleText.replace('http:', location.protocol))

// Highlight result element
$('#result').each(function (i, block) {
hljs.highlightBlock(block);
});

function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}

function json(response) {
return response.json()
}

// Run example
$('#run').click(function () {
var root = location.protocol + '//jsonplaceholder.typicode.com';
fetch(root + '/posts/1')
.then(status)
.then(json)
.then(function (data) {
var str = JSON.stringify(data, null, '\t')
$('#result').html(
str.replace(/\n/g, '<br/>')
.replace(/\\n/g, ' ')
.replace(/\t/g, '&nbsp;&nbsp;')
);

$('#result').each(function (i, block) {
hljs.highlightBlock(block);
});
});
});
</script>
</body>

Expand Down

0 comments on commit 2a0183b

Please sign in to comment.