Skip to content

Commit 6b8f2b2

Browse files
Zé Bateiraterichadbourne
Zé Bateira
andauthored
fix: lost references to the files.add method changed to files.addAll (#493)
* fix: lost references to the files.add method changed to files.addAll * text edits to lesson 3 * text edits to lessons 3,5,6 * text edits to 03.js * fix typo in update message Co-authored-by: terichadbourne <[email protected]>
1 parent 4d95f76 commit 6b8f2b2

File tree

10 files changed

+83
-50
lines changed

10 files changed

+83
-50
lines changed

src/static/tutorials.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@
212212
"title": "Regular Files API",
213213
"description": "The IPFS Regular Files API provides a way to store and share files in a peer-to-peer storage system.",
214214
"newMessage": "",
215-
"updateMessage": "Version `0.48` of `js-ipfs` has introduced some changes, most notably by adding `files.addAll` to use with multiple files, while `files.add` can now only be used with a single file. This means that **some code challenge solutions have changed**. We recommend re-visiting this tutorial to learn about the updated methods and complete the revised challenges!",
215+
"updateMessage": "Version `0.48` of `js-ipfs` has introduced some changes, most notably by adding `addAll` to use with multiple files, while `add` can now only be used with a single file. This means that **some code challenge solutions have changed**. We recommend re-visiting this tutorial to learn about the updated methods and complete the revised challenges!",
216216
"createdAt": "2019-01-01T00:00:00.000Z",
217217
"updatedAt": "2020-07-20T00:00:00.000Z",
218218
"resources": [
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
Add the files in your browser (available in the `files` array below) to your IPFS node using the `add` method.
1+
Add the files in your browser (available in the `files` array below) to your IPFS node using the `addAll` method. Alternatively, you can use the `add` method to upload a single file. Return the results.
22

33
**Hints:**
4-
- You can pass either a single `File` object or an array of `File` objects to the `add` method.
5-
- You need to concatenate all the results into an array because the `ipfs.add` method returns an `Async Iterable`. You can use either the `for await...of` loop or the function `all`.
4+
- You can either pass an array of `File` objects to the `addAll` method or a single `File` object to the `add` method.
5+
- When using the `addAll` method, you'll need to concatenate all the results into an array because the method returns an `Async Iterable`. You can use either the `for await...of` loop or the function `all` to do this.
6+
- When uploading a single file via the `add` method, be sure to pass only the file to the `add` method, instead of passing the whole `files` array.

src/tutorials/0005-regular-files-api/03.js

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,10 @@ import all from 'it-all'
22

33
import utils from '../utils'
44

5-
const validate = async (result, ipfs) => {
6-
const uploadedFiles = window.uploadedFiles || false
7-
5+
async function validateMultipleFiles (result, uploadedFiles, { ipfs }) {
86
const iterable = ipfs.addAll(window.uploadedFiles)
97
const expectedResult = await all(iterable)
108

11-
if (!result) {
12-
return {
13-
fail: utils.validationMessages.NO_RESULT
14-
}
15-
}
16-
17-
if (result.error) {
18-
return { error: result.error }
19-
}
20-
21-
if (utils.validators.isAsyncIterable(result)) {
22-
return {
23-
fail: utils.validationMessages.VALUE_IS_ASYNC_ITERABLE_ALL
24-
}
25-
}
26-
27-
if (!Array.isArray(result)) {
28-
return {
29-
fail: 'The returned value should be an array.'
30-
}
31-
}
32-
339
if (result.length > uploadedFiles.length) {
3410
return {
3511
fail: 'The array you returned has more items than the number of files you uploaded. Be sure to add each file to IPFS just once, which you can do most easily by passing the whole array to the `add` method.'
@@ -50,10 +26,10 @@ const validate = async (result, ipfs) => {
5026
return {
5127
success: utils.validationMessages.SUCCESS,
5228
logDesc: [
53-
"Your `addAll` command returned the array of objects below. The output is very long because the CID is represented as an `Object` internally, but if you scroll down we'll offer you a more condensed view.",
29+
"You returned the array of objects below. The output is very long because the CID is represented as an `Object` internally, but if you scroll down we'll offer you a more condensed view.",
5430
`<pre class="code-highlight"><code class="hljs json">${JSON.stringify(result, null, 2)}</code></pre>`,
5531
'To simplify the output, we can use the `toString()` method on the `cid` property to get the CID in string format: `QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`. In future lessons we\'ll always show this simplified version to make it easier to read, as shown below. <br/> <br/>',
56-
'Your `addAll` command returned the array of objects below. Notice in particular the `cid` ' + valueText + ", since we'll need " + thatText + ' to access ' + fileText + ' again later. The `path` matches the `cid` for ' + fileText + ", but we'll see in future lessons that that's not always true."
32+
'You returned the array of objects below. Notice in particular the `cid` ' + valueText + ", since we'll need " + thatText + ' to access ' + fileText + ' again later. The `path` matches the `cid` for ' + fileText + ", but we'll see in future lessons that that's not always true."
5733
].join(' '),
5834
log: result.map(utils.format.ipfsObject)
5935
}
@@ -62,6 +38,57 @@ const validate = async (result, ipfs) => {
6238
}
6339
}
6440

41+
async function validateSingleFile (result, uploadedFiles, { ipfs }) {
42+
const expectedResult = await ipfs.add(uploadedFiles[0])
43+
44+
if (uploadedFiles.length > 1) {
45+
return {
46+
fail: 'You uploaded multiple files, but you returned only one single file. To upload a single file with `add`, click "Reset Files" to upload a single file to the code editor. To upload multiple files with `addAll`, be sure to concatenate the Async Iterable result from `addAll` into an array.'
47+
}
48+
}
49+
50+
if (JSON.stringify(expectedResult) === JSON.stringify(result)) {
51+
return {
52+
success: utils.validationMessages.SUCCESS,
53+
logDesc: [
54+
"You returned the object bellow. The output is very long because the CID is represented as an `Object` internally, but if you scroll down we'll offer you a more condensed view.",
55+
`<pre class="code-highlight"><code class="hljs json">${JSON.stringify(result, null, 2)}</code></pre>`,
56+
'To simplify the output, we can use the `toString()` method on the `cid` property to get the CID in string format: `QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`. In future lessons we\'ll always show this simplified version to make it easier to read, as shown below. <br/> <br/>',
57+
"You returned the object below. Notice in particular the `cid` value, since we'll need it to access this file again later. The `path` matches the `cid` for this file, but we'll see in future lessons that that's not always true."
58+
].join(' '),
59+
log: utils.format.ipfsObject(result)
60+
}
61+
} else {
62+
return { fail: `Something seems to be wrong. Please click "Reset Code" and try again, taking another look at the instructions and editing only the portion of code indicated. Feeling really stuck? You can click "View Solution" to see our suggested code.` }
63+
}
64+
}
65+
66+
const validate = async (result, ipfs) => {
67+
const uploadedFiles = window.uploadedFiles || false
68+
69+
if (!result) {
70+
return {
71+
fail: utils.validationMessages.NO_RESULT
72+
}
73+
}
74+
75+
if (result.error) {
76+
return { error: result.error }
77+
}
78+
79+
if (utils.validators.isAsyncIterable(result)) {
80+
return {
81+
fail: utils.validationMessages.VALUE_IS_ASYNC_ITERABLE_ALL
82+
}
83+
}
84+
85+
if (Array.isArray(result)) {
86+
return validateMultipleFiles(result, uploadedFiles, { ipfs })
87+
} else {
88+
return validateSingleFile(result, uploadedFiles, { ipfs })
89+
}
90+
}
91+
6592
const code = `/* global ipfs, all */
6693
6794
const run = async (files) => {
@@ -84,6 +111,9 @@ const run = async (files) => {
84111
// result.push(resultPart)
85112
//}
86113
114+
// or when uploading one file
115+
// const result = await ipfs.add(files[0])
116+
87117
return result
88118
}
89119
return run

src/tutorials/0005-regular-files-api/03.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ We create these IPFS nodes behind the scenes so that you can focus on the conten
1010

1111
As mentioned previously, the methods discussed in this tutorial are part of the IPFS [Files API](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md). Check the documentation for more specific details, such as options for each API method.
1212

13-
## Add a file
13+
## Add a single file with `add`
1414

1515
In order to make a file available on the IPFS network, you first need to add it to a specific IPFS node. It's important to remember that because IPFS is a peer-to-peer, decentralized system, adding a file doesn't mean uploading it to a remote server somewhere. Assuming you're using a node on your own machine, the process is more like picking a file from your computer and adding a label to it that says, "I'm shared on IPFS! My name is ______. Come find me!" That label includes a Content Identifier (CID) derived from the file's contents that serves as a type of address that other peers can use to find a specific file, regardless of whose computer it's hosted on.
1616

@@ -39,15 +39,17 @@ The value of the variable `result` is an object in the following format:
3939
}
4040
```
4141

42+
## Add multiple files with `addAll`
43+
4244
If you have more than one adorable animal photo to add to the node, use the `addAll` method instead:
4345

4446
```javascript
4547
ipfs.addAll([catPic, dogPic, giraffePic])
4648
```
4749

48-
Because the `addAll` method returns an [`Async Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of), you can only iterate over the values, one by one. If you need to return all the values, you can save each one into an array and then return the array.
50+
Because the `addAll` method returns an [`Async Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of), you can only iterate over its values, one by one. If you need to return all the values, you can save each one into an array and then return the array.
4951

50-
To iterate over all the values, we can use a `for await...of` loop:
52+
To iterate over all the values of the `Async Iterable`, we can use a `for await...of` loop:
5153

5254
```javascript
5355
const result = []
@@ -68,7 +70,7 @@ To make things easier, we can use the [`it-all`](https://www.npmjs.com/package/i
6870
const result = await all(ipfs.addAll([catPic, dogPic, giraffePic]))
6971
```
7072

71-
The value of the variable `result` is an array of objects identical to the output of `add`, one for each file added to IPFS, in the following format:
73+
The value of the variable `result` is an array of objects (each identical in format to the output of `add`), one for each file added to IPFS, in the following format:
7274

7375
```javascript
7476
{
@@ -81,4 +83,4 @@ The value of the variable `result` is an array of objects identical to the outpu
8183

8284
The value of the `cid` is a CID object (Content Identifier), a unique address generated from the contents of each file. (For a more in-depth look at how CIDs are generated and why they're important, check out our [Decentralized data structures](https://proto.school/#/data-structures) tutorial.) In a future lesson, we will learn how to use this value to retrieve the contents of a file.
8385

84-
The `add` method accepts other `data` formats besides the `File` object and offers many advanced `options` for setting your chunk size and hashing algorithm, pinning files as they're added, and more. We're highlighting the basics in this tutorial, but you can check out the [full documentation](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options) to learn more.
86+
The `add` and `addAll` methods accept other data formats besides the `File` object and offer many advanced options for setting your chunk size and hashing algorithm, pinning files as they're added, and more. We're highlighting the basics in this tutorial, but you can check out the full documentation for the [`add`](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options) or [`addAll`](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsaddallsource-options) methods to learn more.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
Add one or more files to your IPFS node, using `{ wrapWithDirectory: true }` to put them in a directory. Because you're targeting the top-level directory, not a subdirectory, the `path` of each file should just be its name.
1+
Add multiple files to your IPFS node with `addAll`, using `{ wrapWithDirectory: true }` to put them in a directory. Because you're targeting the top-level directory, not a subdirectory, the `path` of each file should just be its name.
22

33
**Hints:**
44
- Be sure to reference the examples above for the object structure needed to indicate the desired path of each file, as well as how to pass in multiple files as an array.
55
- Try the [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) or [`forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) array methods to loop through each file in the `files` array and access its name as `file.name`.
6-
- You need to concatenate all the results into an array because the `ipfs.add` method returns an `Async Iterable`. You can use either the `for await...of` loop or the function `all`.
6+
- You need to concatenate all the results into an array because the `ipfs.addAll` method returns an `Async Iterable`. You can use either the `for await...of` loop or the function `all`.

src/tutorials/0005-regular-files-api/05.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const validate = async (result, ipfs) => {
5757
const resultingFiles = await pTimeout(all(ipfs.ls(result[result.length - 1].cid.toString())), 5000).catch(() => 'error')
5858
if (resultingFiles === 'error') {
5959
return {
60-
fail: 'Could not get CID of top-level directory. Please make sure you are returning the result of the `add` method. The items of the array should be objects with a `cid` attribute whose value must be a valid CID.'
60+
fail: 'Could not get CID of top-level directory. Please make sure you are returning the result of the `addAll` method. The items of the array should be objects with a `cid` attribute whose value must be a valid CID.'
6161
}
6262
} else {
6363
if (resultingFiles.length !== uploadedFiles.length) {
@@ -74,9 +74,9 @@ const validate = async (result, ipfs) => {
7474
if (JSON.stringify(result) === JSON.stringify(expectedResults)) {
7575
return {
7676
success: 'Success!',
77-
logDesc: "Here are the results returned by the `add` method. Note that you have one object for each file, plus one for each directory created by the `{ wrapWithDirectory: true }` option (in this case, just the top-level directory with path `''`)." +
77+
logDesc: "Here are the results returned by the `addAll` method. Note that you have one object for each file, plus one for each directory created by the `{ wrapWithDirectory: true }` option (in this case, just the top-level directory with path `''`)." +
7878
"\n\n Because you used the `{ wrapWithDirectory: true }` option, the `path` of each file is now the filename you provided, rather than matching the file's `cid`. You'll be able to use these human-readable paths to in combination with the directory's CID to access the file's content in a future lesson." +
79-
"\n\n We only have access to the added files' and directories' CIDs when the `add` method returns them. When you use this method in the future, you may want to save them for later use.",
79+
"\n\n We only have access to the added files' and directories' CIDs when the `addAll` method returns them. When you use this method in the future, you may want to save them for later use.",
8080
log: result.map(utils.format.ipfsObject)
8181
}
8282
} else {

0 commit comments

Comments
 (0)