Skip to content

Commit 207fbe8

Browse files
committed
minor
1 parent e828850 commit 207fbe8

File tree

3 files changed

+51
-40
lines changed

3 files changed

+51
-40
lines changed

5-network/01-fetch/01-fetch-users/solution.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11

2-
To fetch a user we need:
2+
To fetch a user we need: `fetch('https://api.github.com/users/USERNAME')`.
33

4-
1. `fetch('https://api.github.com/users/USERNAME')`.
5-
2. If the response has status `200`, call `.json()` to read the JS object.
4+
If the response has status `200`, call `.json()` to read the JS object.
65

7-
If a `fetch` fails, or the response has non-200 status, we just return `null` in the resulting arrray.
6+
Otherwise, if a `fetch` fails, or the response has non-200 status, we just return `null` in the resulting arrray.
87

98
So here's the code:
109

@@ -38,4 +37,4 @@ Please note: `.then` call is attached directly to `fetch`, so that when we have
3837

3938
If we used `await Promise.all(names.map(name => fetch(...)))`, and call `.json()` on the results, then it would wait for all fetches to respond. By adding `.json()` directly to each `fetch`, we ensure that individual fetches start reading data as JSON without waiting for each other.
4039

41-
That's an example of how low-level `Promise` API can still be useful even if we mainly use `async/await`.
40+
That's an example of how low-level Promise API can still be useful even if we mainly use `async/await`.

5-network/01-fetch/01-fetch-users/task.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ There's a test example in the sandbox.
88

99
Important details:
1010

11-
1. There should be one `fetch` request per user. And requests shouldn't wait for each other. So that the data arrives as soon as possible.
12-
2. If any request fails, or if there's no such user, the function should return `null` in the resulting array.
11+
1. There should be one `fetch` request per user.
12+
2. Requests shouldn't wait for each other. So that the data arrives as soon as possible.
13+
3. If any request fails, or if there's no such user, the function should return `null` in the resulting array.

5-network/01-fetch/article.md

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
JavaScript can send network requests to the server and load new information whenever is needed.
55

6-
For example, we can:
6+
For example, we can use a network request to:
77

88
- Submit an order,
99
- Load user information,
@@ -12,11 +12,11 @@ For example, we can:
1212

1313
...And all of that without reloading the page!
1414

15-
There's an umbrella term "AJAX" (abbreviated <b>A</b>synchronous <b>J</b>avascript <b>A</b>nd <b>X</b>ml) for that. We don't have to use XML though: the term comes from old times, that's that word is there.
15+
There's an umbrella term "AJAX" (abbreviated <b>A</b>synchronous <b>J</b>avaScript <b>A</b>nd <b>X</b>ML) for network requests from JavaScript. We don't have to use XML though: the term comes from old times, that's that word is there. You may have heard that term already.
1616

1717
There are multiple ways to send a network request and get information from the server.
1818

19-
The `fetch()` method is modern and versatile, so we'll start with it. It evolved for several years and continues to improve, right now the support is pretty solid among browsers.
19+
The `fetch()` method is modern and versatile, so we'll start with it. It's not supported by old browsers (can be polyfilled), but very well supported among the new ones.
2020

2121
The basic syntax is:
2222

@@ -27,28 +27,28 @@ let promise = fetch(url, [options])
2727
- **`url`** -- the URL to access.
2828
- **`options`** -- optional parameters: method, headers etc.
2929

30-
The browser starts the request right away and returns a `promise`.
30+
The browser starts the request right away and returns a promise that the calling code should use to get the result.
3131

3232
Getting a response is usually a two-stage process.
3333

3434
**First, the `promise` resolves with an object of the built-in [Response](https://fetch.spec.whatwg.org/#response-class) class as soon as the server responds with headers.**
3535

36-
So we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet.
36+
At this stage we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet.
3737

38-
The promise rejects if the `fetch` was unable to make HTTP-request, e.g. network problems, or there's no such site. HTTP-errors, even such as 404 or 500, are considered a normal flow.
38+
The promise rejects if the `fetch` was unable to make HTTP-request, e.g. network problems, or there's no such site. Abnormal HTTP-statuses, such as 404 or 500 do not cause an error.
3939

40-
We can see them in response properties:
40+
We can see HTTP-status in response properties:
4141

42+
- **`status`** -- HTTP status code, e.g. 200.
4243
- **`ok`** -- boolean, `true` if the HTTP status code is 200-299.
43-
- **`status`** -- HTTP status code.
4444

4545
For example:
4646

4747
```js
4848
let response = await fetch(url);
4949

5050
if (response.ok) { // if HTTP-status is 200-299
51-
// get the response body (see below)
51+
// get the response body (the method explained below)
5252
let json = await response.json();
5353
} else {
5454
alert("HTTP-Error: " + response.status);
@@ -59,17 +59,18 @@ if (response.ok) { // if HTTP-status is 200-299
5959

6060
`Response` provides multiple promise-based methods to access the body in various formats:
6161

62-
- **`response.json()`** -- parse the response as JSON object,
63-
- **`response.text()`** -- return the response as text,
64-
- **`response.formData()`** -- return the response as `FormData` object (form/multipart encoding, explained in the [next chapter](info:formdata)),
62+
- **`response.text()`** -- read the response and return as text,
63+
- **`response.json()`** -- parse the response as JSON,
64+
- **`response.formData()`** -- return the response as `FormData` object (explained in the [next chapter](info:formdata)),
6565
- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
66-
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (pure binary data),
66+
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level representaion of binary data),
6767
- additionally, `response.body` is a [ReadableStream](https://streams.spec.whatwg.org/#rs-class) object, it allows to read the body chunk-by-chunk, we'll see an example later.
6868

6969
For instance, let's get a JSON-object with latest commits from GitHub:
7070

7171
```js run async
72-
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
72+
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits';
73+
let response = await fetch(url);
7374

7475
*!*
7576
let commits = await response.json(); // read response body and parse as JSON
@@ -86,7 +87,8 @@ fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commi
8687
.then(commits => alert(commits[0].author.login));
8788
```
8889

89-
To get the text, `await response.text()` instead of `.json()`:
90+
To get the reponse text, `await response.text()` instead of `.json()`:
91+
9092
```js run async
9193
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
9294

@@ -95,7 +97,7 @@ let text = await response.text(); // read response body as text
9597
alert(text.slice(0, 80) + '...');
9698
```
9799

98-
As a show-case for reading in binary format, let's fetch and show an image (see chapter [Blob](info:blob) for details about operations on blobs):
100+
As a show-case for reading in binary format, let's fetch and show a logo image of ["fetch" specification](https://fetch.spec.whatwg.org) (see chapter [Blob](info:blob) for details about operations on `Blob`):
99101

100102
```js async run
101103
let response = await fetch('/article/fetch/logo-fetch.svg');
@@ -119,20 +121,20 @@ setTimeout(() => { // hide after three seconds
119121
```
120122

121123
````warn
122-
We can choose only one body-parsing method.
124+
We can choose only one body-reading method.
123125
124-
If we got the response with `response.text()`, then `response.json()` won't work, as the body content has already been processed.
126+
If we've already got the response with `response.text()`, then `response.json()` won't work, as the body content has already been processed.
125127
126128
```js
127129
let text = await response.text(); // response body consumed
128130
let parsed = await response.json(); // fails (already consumed)
129131
````
130132

131-
## Headers
133+
## Response headers
132134

133-
There's a Map-like headers object in `response.headers`.
135+
The response headers are available in a Map-like headers object in `response.headers`.
134136

135-
We can get individual headers or iterate over them:
137+
It's not exactly a Map, but it has similar methods to get individual headers by name or iterate over them:
136138

137139
```js run async
138140
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
@@ -146,12 +148,14 @@ for (let [key, value] of response.headers) {
146148
}
147149
```
148150

149-
To set a header, we can use the `headers` option, like this:
151+
## Request headers
152+
153+
To set a request header in `fetch`, we can use the `headers` option. It has an object with outgoing headers, like this:
150154

151155
```js
152156
let response = fetch(protectedUrl, {
153157
headers: {
154-
Authentication: 'abcdef'
158+
Authentication: 'secret'
155159
}
156160
});
157161
```
@@ -186,12 +190,14 @@ These headers ensure proper and safe HTTP, so they are controlled exclusively by
186190
To make a `POST` request, or a request with another method, we need to use `fetch` options:
187191

188192
- **`method`** -- HTTP-method, e.g. `POST`,
189-
- **`body`** -- one of:
190-
- a string (e.g. JSON),
193+
- **`body`** -- the request body, one of:
194+
- a string (e.g. JSON-encoded),
191195
- `FormData` object, to submit the data as `form/multipart`,
192196
- `Blob`/`BufferSource` to send binary data,
193197
- [URLSearchParams](info:url), to submit the data in `x-www-form-urlencoded` encoding, rarely used.
194198

199+
The JSON format is used most of the time.
200+
195201
For example, this code submits `user` object as JSON:
196202

197203
```js run async
@@ -214,13 +220,15 @@ let result = await response.json();
214220
alert(result.message);
215221
```
216222

217-
Please note, if the body is a string, then `Content-Type` is set to `text/plain;charset=UTF-8` by default. So we use `headers` option to send `application/json` instead, that's the correct content type for JSON-encoded data.
223+
Please note, if the request `body` is a string, then `Content-Type` header is set to `text/plain;charset=UTF-8` by default.
224+
225+
But, as we're going to send JSON, we use `headers` option to send `application/json` instead, the correct `Content-Type` for JSON-encoded data.
218226

219227
## Sending an image
220228

221-
We can also submit binary data directly using `Blob` or `BufferSource`.
229+
We can also submit binary data with `fetch` using `Blob` or `BufferSource` objects.
222230

223-
For example, here's a `<canvas>` where we can draw by moving a mouse. A click on the "submit" button sends the image to server:
231+
In this example, there's a `<canvas>` where we can draw by moving a mouse over it. A click on the "submit" button sends the image to server:
224232

225233
```html run autorun height="90"
226234
<body style="margin:0">
@@ -241,6 +249,8 @@ For example, here's a `<canvas>` where we can draw by moving a mouse. A click on
241249
method: 'POST',
242250
body: blob
243251
});
252+
253+
// the server responds with confirmation and the image size
244254
let result = await response.json();
245255
alert(result.message);
246256
}
@@ -249,7 +259,7 @@ For example, here's a `<canvas>` where we can draw by moving a mouse. A click on
249259
</body>
250260
```
251261

252-
Here we also didn't need to set `Content-Type` manually, because a `Blob` object has a built-in type (here `image/png`, as generated by `toBlob`).
262+
Please note, here we don't set `Content-Type` header manually, because a `Blob` object has a built-in type (here `image/png`, as generated by `toBlob`). For `Blob` objects that type becomes the value of `Content-Type`.
253263

254264
The `submit()` function can be rewritten without `async/await` like this:
255265

@@ -275,7 +285,8 @@ let response = await fetch(url, options); // resolves with response headers
275285
let result = await response.json(); // read body as json
276286
```
277287

278-
Or, promise-style:
288+
Or, without `await`:
289+
279290
```js
280291
fetch(url, options)
281292
.then(response => response.json())
@@ -288,15 +299,15 @@ Response properties:
288299
- `response.headers` -- Map-like object with HTTP headers.
289300

290301
Methods to get response body:
291-
- **`response.json()`** -- parse the response as JSON object,
292302
- **`response.text()`** -- return the response as text,
303+
- **`response.json()`** -- parse the response as JSON object,
293304
- **`response.formData()`** -- return the response as `FormData` object (form/multipart encoding, see the next chapter),
294305
- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
295-
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (pure binary data),
306+
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level binary data),
296307

297308
Fetch options so far:
298309
- `method` -- HTTP-method,
299310
- `headers` -- an object with request headers (not any header is allowed),
300-
- `body` -- `string`, `FormData`, `BufferSource`, `Blob` or `UrlSearchParams` object to send.
311+
- `body` -- the data to send (request body) as `string`, `FormData`, `BufferSource`, `Blob` or `UrlSearchParams` object.
301312

302313
In the next chapters we'll see more options and use cases of `fetch`.

0 commit comments

Comments
 (0)