From 466b0786fd44d40e886e4819285bf6bb08ce7860 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:28:17 -0300 Subject: [PATCH 01/15] chore: updated step02 --- src/simple-todos/step02/imports/ui/App.svelte | 21 ++++++---- src/simple-todos/step02/server/main.js | 7 ++-- tutorial/simple-todos/02-collections.md | 38 ++++++++++++------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/simple-todos/step02/imports/ui/App.svelte b/src/simple-todos/step02/imports/ui/App.svelte index 3f1b70f..aa9e1a3 100644 --- a/src/simple-todos/step02/imports/ui/App.svelte +++ b/src/simple-todos/step02/imports/ui/App.svelte @@ -2,18 +2,25 @@ import Task from './Task.svelte'; import { TasksCollection } from '../api/TasksCollection'; - $m: tasks = TasksCollection.find({}).fetch() + let getTasks; + $m: getTasks = TasksCollection.find({}).fetchAsync()
-

Todo List

+

Todo List

- + {#await getTasks} +

Loading...

+ {:then tasks} + + {:catch error} +

{error.message}

+ {/await}
diff --git a/src/simple-todos/step02/server/main.js b/src/simple-todos/step02/server/main.js index cd5ce50..896720a 100644 --- a/src/simple-todos/step02/server/main.js +++ b/src/simple-todos/step02/server/main.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/02-collections.md b/tutorial/simple-todos/02-collections.md index c21c51b..9062be2 100644 --- a/tutorial/simple-todos/02-collections.md +++ b/tutorial/simple-todos/02-collections.md @@ -37,10 +37,11 @@ You don't need to keep the old content of `server/main.js`. import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); - -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); + +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', @@ -48,10 +49,11 @@ Meteor.startup(() => { 'Fourth Task', 'Fifth Task', 'Sixth Task', - 'Seventh Task' - ].forEach(insertTask) + 'Seventh Task', + ].forEach(insertTask); } }); + ``` So you are importing the `TasksCollection` and adding a few tasks to it over an array of strings, and for each string, calling a function to insert this string as our `text` field in our `task` document. @@ -62,13 +64,15 @@ Now comes the fun part, you will render the tasks saved in our database. With Sv On your file `App.svelte`, import the `TasksCollection` file and, instead of returning a static array, return the tasks saved in the database. Let's use an extension of the Svelte's [$ reactive statements](https://svelte.dev/docs#3_$_marks_a_statement_as_reactive) feature, to maintain your tasks, called [$m](https://github.com/zodern/melte#tracker-statements): +Because it is an asynchronous function, we need to use the `#await` keyword to wait for the data to be fetched from the database. More information about how Svelte handles asynchronous values can be found [here](https://svelte.dev/docs#template-syntax-await). + `imports/ui/App.svelte` -```html +```sveltehtml @@ -77,11 +81,17 @@ On your file `App.svelte`, import the `TasksCollection` file and, instead of ret

Todo List

- + {#await getTasks} +

Loading...

+ {:then tasks} + + {:catch error} +

{error.message}

+ {/await} ``` From c4239b87bfe24742f498363d0dcf1acdf06178b2 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:28:34 -0300 Subject: [PATCH 02/15] chore: updated step03 --- src/simple-todos/step03/imports/ui/App.svelte | 23 ++++++++++++------- .../step03/imports/ui/TaskForm.svelte | 4 ++-- src/simple-todos/step03/server/main.js | 7 +++--- tutorial/simple-todos/03-forms-and-events.md | 9 ++++---- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/simple-todos/step03/imports/ui/App.svelte b/src/simple-todos/step03/imports/ui/App.svelte index 64491ba..06f23bf 100644 --- a/src/simple-todos/step03/imports/ui/App.svelte +++ b/src/simple-todos/step03/imports/ui/App.svelte @@ -3,20 +3,27 @@ import Task from './Task.svelte'; import TaskForm from './TaskForm.svelte'; - $m: tasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetch() + let getTasks; + $m: getTasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetchAsync()
-

Todo List

+

Todo List

- + -
    - {#each tasks as task (task._id)} - - {/each} -
+ {#await getTasks} +

Loading...

+ {:then tasks} +
    + {#each tasks as task (task._id)} + + {/each} +
+ {:catch error} +

{error.message}

+ {/await}
diff --git a/src/simple-todos/step03/imports/ui/TaskForm.svelte b/src/simple-todos/step03/imports/ui/TaskForm.svelte index d0bdb47..7e51106 100644 --- a/src/simple-todos/step03/imports/ui/TaskForm.svelte +++ b/src/simple-todos/step03/imports/ui/TaskForm.svelte @@ -3,9 +3,9 @@ let newTask = ''; - const handleSubmit = () => { + const handleSubmit = async () => { // Insert a task into the collection - TasksCollection.insert({ + await TasksCollection.insertAsync({ text: newTask, createdAt: new Date(), // current time }); diff --git a/src/simple-todos/step03/server/main.js b/src/simple-todos/step03/server/main.js index cd5ce50..896720a 100644 --- a/src/simple-todos/step03/server/main.js +++ b/src/simple-todos/step03/server/main.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/03-forms-and-events.md b/tutorial/simple-todos/03-forms-and-events.md index 2e9bb9f..76fc561 100644 --- a/tutorial/simple-todos/03-forms-and-events.md +++ b/tutorial/simple-todos/03-forms-and-events.md @@ -27,7 +27,7 @@ Then we can simply add this new form to our `App.svelte` component by first impo `imports/ui/App.svelte` -```html +```sveltehtml .. ``` From 62fdfda384af655ea237c25f6a5ee066928b54ba Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:28:59 -0300 Subject: [PATCH 03/15] chore: updated step04 --- src/simple-todos/step04/imports/ui/App.svelte | 20 +++++++++++++------ .../step04/imports/ui/Task.svelte | 8 ++++---- .../step04/imports/ui/TaskForm.svelte | 4 ++-- src/simple-todos/step04/server/main.js | 7 ++++--- tutorial/simple-todos/04-update-and-remove.md | 16 +++++++-------- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/simple-todos/step04/imports/ui/App.svelte b/src/simple-todos/step04/imports/ui/App.svelte index 64491ba..08c5124 100644 --- a/src/simple-todos/step04/imports/ui/App.svelte +++ b/src/simple-todos/step04/imports/ui/App.svelte @@ -3,7 +3,8 @@ import Task from './Task.svelte'; import TaskForm from './TaskForm.svelte'; - $m: tasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetch() + let getTasks; + $m: getTasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetchAsync() @@ -14,9 +15,16 @@ - + + {#await getTasks} +

Loading...

+ {:then tasks} + + {:catch error} +

{error.message}

+ {/await} diff --git a/src/simple-todos/step04/imports/ui/Task.svelte b/src/simple-todos/step04/imports/ui/Task.svelte index 3ad80ff..3fffb82 100644 --- a/src/simple-todos/step04/imports/ui/Task.svelte +++ b/src/simple-todos/step04/imports/ui/Task.svelte @@ -3,15 +3,15 @@ export let task; - const toggleChecked = () => { + const toggleChecked = async () => { // Set the checked property to the opposite of its current value - TasksCollection.update(task._id, { + await TasksCollection.updateAsync(task._id, { $set: { isChecked: !task.isChecked } }); }; - const deleteThisTask = () => { - TasksCollection.remove(task._id); + const deleteThisTask = async () => { + await TasksCollection.removeAsync(task._id); }; diff --git a/src/simple-todos/step04/imports/ui/TaskForm.svelte b/src/simple-todos/step04/imports/ui/TaskForm.svelte index d0bdb47..7e51106 100644 --- a/src/simple-todos/step04/imports/ui/TaskForm.svelte +++ b/src/simple-todos/step04/imports/ui/TaskForm.svelte @@ -3,9 +3,9 @@ let newTask = ''; - const handleSubmit = () => { + const handleSubmit = async () => { // Insert a task into the collection - TasksCollection.insert({ + await TasksCollection.insertAsync({ text: newTask, createdAt: new Date(), // current time }); diff --git a/src/simple-todos/step04/server/main.js b/src/simple-todos/step04/server/main.js index cd5ce50..896720a 100644 --- a/src/simple-todos/step04/server/main.js +++ b/src/simple-todos/step04/server/main.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/04-update-and-remove.md b/tutorial/simple-todos/04-update-and-remove.md index 3a26959..3f1918b 100644 --- a/tutorial/simple-todos/04-update-and-remove.md +++ b/tutorial/simple-todos/04-update-and-remove.md @@ -10,7 +10,7 @@ First, you need to add a `checkbox` element to your `Task` component: `imports/ui/Task.svelte` -```html +```sveltehtml
  • { - // Set the isChecked property to the opposite of its current value - TasksCollection.update(task._id, { - $set: { isChecked: !task.isChecked } - }); + const toggleChecked = async () => { + // Set the checked property to the opposite of its current value + await TasksCollection.updateAsync(task._id, { + $set: { isChecked: !task.isChecked } + }); }; .. @@ -78,8 +78,8 @@ Now add the removal logic inside the ` .. From ae03ef7cfa93ae444bc98206c5032fe6d5f8a2f1 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:29:13 -0300 Subject: [PATCH 04/15] chore: updated step05 --- src/simple-todos/step05/imports/ui/App.svelte | 20 ++++++++++++------- .../step05/imports/ui/Task.svelte | 8 ++++---- .../step05/imports/ui/TaskForm.svelte | 4 ++-- src/simple-todos/step05/server/main.js | 7 ++++--- tutorial/simple-todos/05-styles.md | 19 +++++++++++------- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/simple-todos/step05/imports/ui/App.svelte b/src/simple-todos/step05/imports/ui/App.svelte index c2d2f8a..b7d8ecf 100644 --- a/src/simple-todos/step05/imports/ui/App.svelte +++ b/src/simple-todos/step05/imports/ui/App.svelte @@ -3,7 +3,8 @@ import Task from './Task.svelte'; import TaskForm from './TaskForm.svelte'; - $m: tasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetch() + let getTasks; + $m: getTasks = TasksCollection.find({}, { sort: { createdAt: -1 } }).fetchAsync() @@ -18,11 +19,16 @@
    - -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} +

    Loading...

    + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await}
    diff --git a/src/simple-todos/step05/imports/ui/Task.svelte b/src/simple-todos/step05/imports/ui/Task.svelte index 3ad80ff..3fffb82 100644 --- a/src/simple-todos/step05/imports/ui/Task.svelte +++ b/src/simple-todos/step05/imports/ui/Task.svelte @@ -3,15 +3,15 @@ export let task; - const toggleChecked = () => { + const toggleChecked = async () => { // Set the checked property to the opposite of its current value - TasksCollection.update(task._id, { + await TasksCollection.updateAsync(task._id, { $set: { isChecked: !task.isChecked } }); }; - const deleteThisTask = () => { - TasksCollection.remove(task._id); + const deleteThisTask = async () => { + await TasksCollection.removeAsync(task._id); }; diff --git a/src/simple-todos/step05/imports/ui/TaskForm.svelte b/src/simple-todos/step05/imports/ui/TaskForm.svelte index d0bdb47..7e51106 100644 --- a/src/simple-todos/step05/imports/ui/TaskForm.svelte +++ b/src/simple-todos/step05/imports/ui/TaskForm.svelte @@ -3,9 +3,9 @@ let newTask = ''; - const handleSubmit = () => { + const handleSubmit = async () => { // Insert a task into the collection - TasksCollection.insert({ + await TasksCollection.insertAsync({ text: newTask, createdAt: new Date(), // current time }); diff --git a/src/simple-todos/step05/server/main.js b/src/simple-todos/step05/server/main.js index cd5ce50..896720a 100644 --- a/src/simple-todos/step05/server/main.js +++ b/src/simple-todos/step05/server/main.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/05-styles.md b/tutorial/simple-todos/05-styles.md index f8013ba..2951a5e 100644 --- a/tutorial/simple-todos/05-styles.md +++ b/tutorial/simple-todos/05-styles.md @@ -156,7 +156,7 @@ Now you need to add some elements around your components. Also, we need to apply `imports/ui/App.svelte` -```html +```sveltehtml ..
    @@ -169,12 +169,17 @@ Now you need to add some elements around your components. Also, we need to apply
    - -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} +

    Loading...

    + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await}
    From b41c21c14ec258f3c987c373f2c9ce8f838dd74d Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:29:25 -0300 Subject: [PATCH 05/15] chore: updated step06 --- src/simple-todos/step06/imports/ui/App.svelte | 38 +++++++++++-------- .../step06/imports/ui/Task.svelte | 14 +++---- .../step06/imports/ui/TaskForm.svelte | 22 +++++------ src/simple-todos/step06/server/main.js | 7 ++-- tutorial/simple-todos/06-filter-tasks.md | 32 ++++++++-------- 5 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/simple-todos/step06/imports/ui/App.svelte b/src/simple-todos/step06/imports/ui/App.svelte index 0df1f71..c87260f 100644 --- a/src/simple-todos/step06/imports/ui/App.svelte +++ b/src/simple-todos/step06/imports/ui/App.svelte @@ -6,21 +6,19 @@ let hideCompleted = false; const hideCompletedFilter = { isChecked: { $ne: true } }; - - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; $m: { - tasks = TasksCollection.find(hideCompleted ? hideCompletedFilter : {}, { + getTasks = TasksCollection.find(hideCompleted ? hideCompletedFilter : {}, { sort: { createdAt: -1 }, - }).fetch(); - - incompleteCount = TasksCollection.find(hideCompletedFilter).count(); + }).fetchAsync(); - pendingTasksTitle = `${incompleteCount ? ` (${incompleteCount})` : ''}`; + getCount = TasksCollection.find(hideCompletedFilter).countAsync(); } + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; + const setHideCompleted = (value) => { hideCompleted = value; }; @@ -30,7 +28,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -42,10 +44,16 @@ {hideCompleted ? 'Show All' : 'Hide Completed'} - + {#await getTasks} +

    Loading...

    + {:then tasks} + + {:catch error} +

    {error.message}

    + {/await} diff --git a/src/simple-todos/step06/imports/ui/Task.svelte b/src/simple-todos/step06/imports/ui/Task.svelte index 3ad80ff..43911f6 100644 --- a/src/simple-todos/step06/imports/ui/Task.svelte +++ b/src/simple-todos/step06/imports/ui/Task.svelte @@ -3,24 +3,24 @@ export let task; - const toggleChecked = () => { + const toggleChecked = async () => { // Set the checked property to the opposite of its current value - TasksCollection.update(task._id, { + await TasksCollection.updateAsync(task._id, { $set: { isChecked: !task.isChecked } }); }; - const deleteThisTask = () => { - TasksCollection.remove(task._id); + const deleteThisTask = async () => { + await TasksCollection.removeAsync(task._id); };
  • { task.text } diff --git a/src/simple-todos/step06/imports/ui/TaskForm.svelte b/src/simple-todos/step06/imports/ui/TaskForm.svelte index d0bdb47..0f1bc86 100644 --- a/src/simple-todos/step06/imports/ui/TaskForm.svelte +++ b/src/simple-todos/step06/imports/ui/TaskForm.svelte @@ -1,18 +1,18 @@
    diff --git a/src/simple-todos/step06/server/main.js b/src/simple-todos/step06/server/main.js index cd5ce50..896720a 100644 --- a/src/simple-todos/step06/server/main.js +++ b/src/simple-todos/step06/server/main.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = taskText => TasksCollection.insert({ text: taskText }); +const insertTask = async (taskText) => + await TasksCollection.insert({ text: taskText }); -Meteor.startup(() => { - if (TasksCollection.find().count() === 0) { +Meteor.startup(async () => { + if (await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/06-filter-tasks.md b/tutorial/simple-todos/06-filter-tasks.md index a29d725..57364e8 100644 --- a/tutorial/simple-todos/06-filter-tasks.md +++ b/tutorial/simple-todos/06-filter-tasks.md @@ -12,7 +12,7 @@ With Svelte this will be a pretty simple task as we don't have to do much to kee `imports/ui/App.svelte` -```html +```sveltehtml .. @@ -88,7 +88,7 @@ Install it in your Google Chrome browser using this [link](https://chrome.google ## 6.5: Pending tasks -Update the App component in order to show the number of pending tasks in the app bar. +Update the App component in order to show the number of pending tasks in the app bar. Remember that your calls to the database are asynchronous, so you need to use the `#await` keyword to get the data. You should avoid adding zero to your app bar when there are not pending tasks. @@ -97,19 +97,17 @@ You should avoid adding zero to your app bar when there are not pending tasks. @@ -117,7 +115,11 @@ You should avoid adding zero to your app bar when there are not pending tasks.
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    From 5598742f622acb5ae2fb761d0e3c039270811a57 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:29:39 -0300 Subject: [PATCH 06/15] chore: updated step07 --- src/simple-todos/step07/imports/ui/App.svelte | 40 ++++++++------ .../step07/imports/ui/Task.svelte | 14 ++--- .../step07/imports/ui/TaskForm.svelte | 4 +- src/simple-todos/step07/server/main.js | 8 +-- .../simple-todos/07-adding-user-accounts.md | 54 +++++++++++-------- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/simple-todos/step07/imports/ui/App.svelte b/src/simple-todos/step07/imports/ui/App.svelte index 1f16261..4b4fdf3 100644 --- a/src/simple-todos/step07/imports/ui/App.svelte +++ b/src/simple-todos/step07/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; $m: { @@ -22,22 +21,19 @@ const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = user + getTasks = user ? TasksCollection.find( hideCompleted ? pendingOnlyFilter : userFilter, { sort: { createdAt: -1 } } - ).fetch() + ).fetchAsync() : []; - incompleteCount = user - ? TasksCollection.find(pendingOnlyFilter).count() + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() : 0; - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; } - + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; }; @@ -49,7 +45,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -67,11 +67,17 @@ {hideCompleted ? 'Show All' : 'Hide Completed'} -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} +

    Loading...

    + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await} {:else} {/if} diff --git a/src/simple-todos/step07/imports/ui/Task.svelte b/src/simple-todos/step07/imports/ui/Task.svelte index 3ad80ff..43911f6 100644 --- a/src/simple-todos/step07/imports/ui/Task.svelte +++ b/src/simple-todos/step07/imports/ui/Task.svelte @@ -3,24 +3,24 @@ export let task; - const toggleChecked = () => { + const toggleChecked = async () => { // Set the checked property to the opposite of its current value - TasksCollection.update(task._id, { + await TasksCollection.updateAsync(task._id, { $set: { isChecked: !task.isChecked } }); }; - const deleteThisTask = () => { - TasksCollection.remove(task._id); + const deleteThisTask = async () => { + await TasksCollection.removeAsync(task._id); };
  • { task.text } diff --git a/src/simple-todos/step07/imports/ui/TaskForm.svelte b/src/simple-todos/step07/imports/ui/TaskForm.svelte index 2739f49..efe463e 100644 --- a/src/simple-todos/step07/imports/ui/TaskForm.svelte +++ b/src/simple-todos/step07/imports/ui/TaskForm.svelte @@ -4,9 +4,9 @@ export let user = null; let newTask = ''; - const handleSubmit = () => { + const handleSubmit = async () => { // Insert a task into the collection - TasksCollection.insert({ + await TasksCollection.insertAsync({ text: newTask, createdAt: new Date(), // current time userId: user._id, diff --git a/src/simple-todos/step07/server/main.js b/src/simple-todos/step07/server/main.js index cea2c26..b317967 100644 --- a/src/simple-todos/step07/server/main.js +++ b/src/simple-todos/step07/server/main.js @@ -2,8 +2,8 @@ import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; import { TasksCollection } from '/imports/api/TasksCollection'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -12,7 +12,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -22,7 +22,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/07-adding-user-accounts.md b/tutorial/simple-todos/07-adding-user-accounts.md index 66be49b..d3b8c27 100644 --- a/tutorial/simple-todos/07-adding-user-accounts.md +++ b/tutorial/simple-todos/07-adding-user-accounts.md @@ -36,7 +36,7 @@ import { TasksCollection } from '/imports/api/TasksCollection'; const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -112,7 +112,7 @@ You can get your authenticated user or null from `Meteor.user()`. Then you can v `imports/ui/App.svelte` -```html +```sveltehtml @@ -283,17 +289,23 @@ Now you can filter the tasks in the UI by the authenticated user. Use the user ` ..
    .. + {#await getTasks} +

    Loading...

    + {:then tasks}
      {#each tasks as task (task._id)} - + {/each}
    + {:catch error} +

    {error.message}

    + {/await} ..
    ``` -Also update the `insert` call to include the field `userId` in the `TaskForm`. You should pass the user from the `App` component to the `TaskForm`. +Also update the `insertAsync` call to include the field `userId` in the `TaskForm`. You should pass the user from the `App` component to the `TaskForm`. `imports/ui/TaskForm.svelte` ```html @@ -301,9 +313,9 @@ Also update the `insert` call to include the field `userId` in the `TaskForm`. Y .. export let user = null; .. - const handleSubmit = () => { + const handleSubmit = async () => { // Insert a task into the collection - TasksCollection.insert({ + await TasksCollection.insertAsync({ text: newTask, createdAt: new Date(), // current time userId: user._id, From accd5da275a9e8dc10bb5c9f4188c7132d30796b Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:29:53 -0300 Subject: [PATCH 07/15] chore: updated step08 --- .../step08/imports/api/tasksMethods.js | 12 ++--- src/simple-todos/step08/imports/ui/App.svelte | 48 +++++++++++-------- .../step08/imports/ui/Task.svelte | 3 +- src/simple-todos/step08/server/main.js | 8 ++-- tutorial/simple-todos/08-methods.md | 37 +++++++------- 5 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/simple-todos/step08/imports/api/tasksMethods.js b/src/simple-todos/step08/imports/api/tasksMethods.js index 51b06d7..5d2c6e4 100644 --- a/src/simple-todos/step08/imports/api/tasksMethods.js +++ b/src/simple-todos/step08/imports/api/tasksMethods.js @@ -3,31 +3,31 @@ import { check } from 'meteor/check'; import { TasksCollection } from '../db/TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.insert({ + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, }); }, - 'tasks.remove'(taskId) { + async 'tasks.remove'(taskId) { check(taskId, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.remove(taskId); + await TasksCollection.removeAsync(taskId); }, - 'tasks.setIsChecked'(taskId, isChecked) { + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); @@ -35,7 +35,7 @@ Meteor.methods({ throw new Meteor.Error('Not authorized.'); } - TasksCollection.update(taskId, { + await TasksCollection.updateAsync(taskId, { $set: { isChecked, }, diff --git a/src/simple-todos/step08/imports/ui/App.svelte b/src/simple-todos/step08/imports/ui/App.svelte index fe7f014..5626dca 100644 --- a/src/simple-todos/step08/imports/ui/App.svelte +++ b/src/simple-todos/step08/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; $m: { @@ -22,22 +21,19 @@ const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = user + getTasks = user ? TasksCollection.find( - hideCompleted ? pendingOnlyFilter : userFilter, - { sort: { createdAt: -1 } } - ).fetch() + hideCompleted ? pendingOnlyFilter : userFilter, + { sort: { createdAt: -1 } } + ).fetchAsync() : []; - incompleteCount = user - ? TasksCollection.find(pendingOnlyFilter).count() - : 0; + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() + : 0; - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; } - + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; }; @@ -49,7 +45,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -60,18 +60,24 @@ {user.username} 🚪 - +
    -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} +

    Loading...

    + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await} {:else} {/if} diff --git a/src/simple-todos/step08/imports/ui/Task.svelte b/src/simple-todos/step08/imports/ui/Task.svelte index 7d0a4ad..e877fca 100644 --- a/src/simple-todos/step08/imports/ui/Task.svelte +++ b/src/simple-todos/step08/imports/ui/Task.svelte @@ -5,7 +5,8 @@ Meteor.call('tasks.setIsChecked', task._id, !task.isChecked); - const deleteThisTask = () => Meteor.call('tasks.remove', task._id); + const deleteThisTask = () => + Meteor.call('tasks.remove', task._id);
  • diff --git a/src/simple-todos/step08/server/main.js b/src/simple-todos/step08/server/main.js index 4a148bb..99c4751 100644 --- a/src/simple-todos/step08/server/main.js +++ b/src/simple-todos/step08/server/main.js @@ -3,8 +3,8 @@ import { Accounts } from 'meteor/accounts-base'; import { TasksCollection } from '/imports/db/TasksCollection'; import '/imports/api/tasksMethods'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -13,7 +13,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -23,7 +23,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/08-methods.md b/tutorial/simple-todos/08-methods.md index 199f631..bb53b46 100644 --- a/tutorial/simple-todos/08-methods.md +++ b/tutorial/simple-todos/08-methods.md @@ -58,45 +58,46 @@ import { check } from 'meteor/check'; import { TasksCollection } from './TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); - + if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - - TasksCollection.insert({ + + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, - }) + }); }, - - 'tasks.remove'(taskId) { + + async 'tasks.remove'(taskId) { check(taskId, String); - + if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - - TasksCollection.remove(taskId); + + await TasksCollection.removeAsync(taskId); }, - - 'tasks.setIsChecked'(taskId, isChecked) { + + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); - + if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - - TasksCollection.update(taskId, { + + await TasksCollection.updateAsync(taskId, { $set: { - isChecked - } + isChecked, + }, }); - } + }, }); + ``` As you can see in the code we are also using the `check` package to make sure we are receiving the expected types of input, this is important to make sure you know exactly what you are inserting or updating in your database. From fc56dbd83a68f276471de30cf5ce27d2da80f9cd Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:30:12 -0300 Subject: [PATCH 08/15] chore: updated step09 --- .../step09/imports/api/tasksMethods.js | 16 ++-- src/simple-todos/step09/imports/ui/App.svelte | 51 +++++----- src/simple-todos/step09/server/main.js | 8 +- tutorial/simple-todos/09-publications.md | 93 ++++++++++--------- 4 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/simple-todos/step09/imports/api/tasksMethods.js b/src/simple-todos/step09/imports/api/tasksMethods.js index b1ddc18..10f8aa6 100644 --- a/src/simple-todos/step09/imports/api/tasksMethods.js +++ b/src/simple-todos/step09/imports/api/tasksMethods.js @@ -3,37 +3,37 @@ import { check } from 'meteor/check'; import { TasksCollection } from '../db/TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.insert({ + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, }); }, - 'tasks.remove'(taskId) { + async 'tasks.remove'(taskId) { check(taskId, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.remove(taskId); + await TasksCollection.remove(taskId); }, - 'tasks.setIsChecked'(taskId, isChecked) { + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); @@ -41,13 +41,13 @@ Meteor.methods({ throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.update(taskId, { + await TasksCollection.updateAsync(taskId, { $set: { isChecked, }, diff --git a/src/simple-todos/step09/imports/ui/App.svelte b/src/simple-todos/step09/imports/ui/App.svelte index 0b52de6..a483e0b 100644 --- a/src/simple-todos/step09/imports/ui/App.svelte +++ b/src/simple-todos/step09/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; let isLoading = true; @@ -22,24 +21,25 @@ if (user) { - isLoading = !handler.ready(); + isLoading = !handler.ready(); - const userFilter = { userId: user._id }; - const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; + const userFilter = { userId: user._id }; + const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = TasksCollection.find( - hideCompleted ? pendingOnlyFilter : userFilter, - { sort: { createdAt: -1 } } - ).fetch(); + getTasks = user + ? TasksCollection.find( + hideCompleted ? pendingOnlyFilter : userFilter, + { sort: { createdAt: -1 } } + ).fetchAsync() + : []; - incompleteCount = TasksCollection.find(pendingOnlyFilter).count(); - - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() + : 0; } } + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; @@ -52,7 +52,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -75,11 +79,16 @@
    loading...
    {/if} -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await} {:else} {/if} diff --git a/src/simple-todos/step09/server/main.js b/src/simple-todos/step09/server/main.js index 39d8744..7a52216 100644 --- a/src/simple-todos/step09/server/main.js +++ b/src/simple-todos/step09/server/main.js @@ -4,8 +4,8 @@ import { TasksCollection } from '/imports/db/TasksCollection'; import '/imports/api/tasksMethods'; import '/imports/api/tasksPublications'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -14,7 +14,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -24,7 +24,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/09-publications.md b/tutorial/simple-todos/09-publications.md index b013f81..0342334 100644 --- a/tutorial/simple-todos/09-publications.md +++ b/tutorial/simple-todos/09-publications.md @@ -56,7 +56,7 @@ As we want to receive changes from this publication we are going to `subscribe` `imports/ui/App.svelte` -```html +```sveltehtml .. @@ -139,42 +140,42 @@ Only the owner of a task should be able to change certain things. You should cha ```js .. - 'tasks.remove'(taskId) { - check(taskId, String); - - if (!this.userId) { - throw new Meteor.Error('Not authorized.'); - } - - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); - - if (!task) { - throw new Meteor.Error('Access denied.'); - } - - TasksCollection.remove(taskId); - }, - - 'tasks.setIsChecked'(taskId, isChecked) { - check(taskId, String); - check(isChecked, Boolean); - - if (!this.userId) { - throw new Meteor.Error('Not authorized.'); - } - - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); - - if (!task) { - throw new Meteor.Error('Access denied.'); - } - - TasksCollection.update(taskId, { - $set: { - isChecked, - }, - }); - }, + async 'tasks.remove'(taskId) { + check(taskId, String); + + if (!this.userId) { + throw new Meteor.Error('Not authorized.'); + } + + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); + + if (!task) { + throw new Meteor.Error('Access denied.'); + } + + await TasksCollection.remove(taskId); + }, + + async 'tasks.setIsChecked'(taskId, isChecked) { + check(taskId, String); + check(isChecked, Boolean); + + if (!this.userId) { + throw new Meteor.Error('Not authorized.'); + } + + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); + + if (!task) { + throw new Meteor.Error('Access denied.'); + } + + await TasksCollection.updateAsync(taskId, { + $set: { + isChecked, + }, + }); + }, .. ``` From bf8a4b63066b48c39e340f78b151c0d8d6194fff Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:30:26 -0300 Subject: [PATCH 09/15] chore: updated step10 --- .../step10/imports/api/tasksMethods.js | 16 +++--- src/simple-todos/step10/imports/ui/App.svelte | 51 +++++++++++-------- src/simple-todos/step10/server/main.js | 8 +-- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/simple-todos/step10/imports/api/tasksMethods.js b/src/simple-todos/step10/imports/api/tasksMethods.js index b1ddc18..10f8aa6 100644 --- a/src/simple-todos/step10/imports/api/tasksMethods.js +++ b/src/simple-todos/step10/imports/api/tasksMethods.js @@ -3,37 +3,37 @@ import { check } from 'meteor/check'; import { TasksCollection } from '../db/TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.insert({ + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, }); }, - 'tasks.remove'(taskId) { + async 'tasks.remove'(taskId) { check(taskId, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.remove(taskId); + await TasksCollection.remove(taskId); }, - 'tasks.setIsChecked'(taskId, isChecked) { + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); @@ -41,13 +41,13 @@ Meteor.methods({ throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.update(taskId, { + await TasksCollection.updateAsync(taskId, { $set: { isChecked, }, diff --git a/src/simple-todos/step10/imports/ui/App.svelte b/src/simple-todos/step10/imports/ui/App.svelte index 0b52de6..a483e0b 100644 --- a/src/simple-todos/step10/imports/ui/App.svelte +++ b/src/simple-todos/step10/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; let isLoading = true; @@ -22,24 +21,25 @@ if (user) { - isLoading = !handler.ready(); + isLoading = !handler.ready(); - const userFilter = { userId: user._id }; - const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; + const userFilter = { userId: user._id }; + const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = TasksCollection.find( - hideCompleted ? pendingOnlyFilter : userFilter, - { sort: { createdAt: -1 } } - ).fetch(); + getTasks = user + ? TasksCollection.find( + hideCompleted ? pendingOnlyFilter : userFilter, + { sort: { createdAt: -1 } } + ).fetchAsync() + : []; - incompleteCount = TasksCollection.find(pendingOnlyFilter).count(); - - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() + : 0; } } + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; @@ -52,7 +52,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -75,11 +79,16 @@
    loading...
    {/if} -
      - {#each tasks as task (task._id)} - - {/each} -
    + {#await getTasks} + {:then tasks} +
      + {#each tasks as task (task._id)} + + {/each} +
    + {:catch error} +

    {error.message}

    + {/await} {:else} {/if} diff --git a/src/simple-todos/step10/server/main.js b/src/simple-todos/step10/server/main.js index 39d8744..7a52216 100644 --- a/src/simple-todos/step10/server/main.js +++ b/src/simple-todos/step10/server/main.js @@ -4,8 +4,8 @@ import { TasksCollection } from '/imports/db/TasksCollection'; import '/imports/api/tasksMethods'; import '/imports/api/tasksPublications'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -14,7 +14,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -24,7 +24,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', From b34b9265f70038d9a00e0efda108788226d275bc Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:30:40 -0300 Subject: [PATCH 10/15] chore: updated step11 --- .../step11/imports/api/tasksMethods.js | 16 +++--- .../step11/imports/api/tasksMethods.tests.js | 28 +++++----- src/simple-todos/step11/imports/ui/App.svelte | 55 +++++++++++-------- src/simple-todos/step11/server/main.js | 8 +-- tutorial/simple-todos/11-testing.md | 40 +++++++------- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/simple-todos/step11/imports/api/tasksMethods.js b/src/simple-todos/step11/imports/api/tasksMethods.js index b1ddc18..10f8aa6 100644 --- a/src/simple-todos/step11/imports/api/tasksMethods.js +++ b/src/simple-todos/step11/imports/api/tasksMethods.js @@ -3,37 +3,37 @@ import { check } from 'meteor/check'; import { TasksCollection } from '../db/TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.insert({ + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, }); }, - 'tasks.remove'(taskId) { + async 'tasks.remove'(taskId) { check(taskId, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.remove(taskId); + await TasksCollection.remove(taskId); }, - 'tasks.setIsChecked'(taskId, isChecked) { + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); @@ -41,13 +41,13 @@ Meteor.methods({ throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.update(taskId, { + await TasksCollection.updateAsync(taskId, { $set: { isChecked, }, diff --git a/src/simple-todos/step11/imports/api/tasksMethods.tests.js b/src/simple-todos/step11/imports/api/tasksMethods.tests.js index 953269b..e382e79 100644 --- a/src/simple-todos/step11/imports/api/tasksMethods.tests.js +++ b/src/simple-todos/step11/imports/api/tasksMethods.tests.js @@ -11,53 +11,53 @@ if (Meteor.isServer) { const userId = Random.id(); let taskId; - beforeEach(() => { - TasksCollection.remove({}); - taskId = TasksCollection.insert({ + beforeEach(async () => { + await TasksCollection.removeAsync({}); + taskId = await TasksCollection.insertAsync({ text: 'Test Task', createdAt: new Date(), userId, }); }); - it('can delete owned task', () => { + it('can delete owned task', async () => { mockMethodCall('tasks.remove', taskId, { context: { userId } }); - assert.equal(TasksCollection.find().count(), 0); + assert.equal(await TasksCollection.find().countAsync(), 0); }); - it("can't delete task without an user authenticated", () => { + it("can't delete task without an user authenticated", async () => { const fn = () => mockMethodCall('tasks.remove', taskId); assert.throw(fn, /Not authorized/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it("can't delete task from another owner", () => { + it("can't delete task from another owner", async () => { const fn = () => mockMethodCall('tasks.remove', taskId, { context: { userId: 'somebody-else-id' }, }); assert.throw(fn, /Access denied/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it('can change the status of a task', () => { - const originalTask = TasksCollection.findOne(taskId); + it('can change the status of a task', async () => { + const originalTask = await TasksCollection.findOneAsync(taskId); mockMethodCall('tasks.setIsChecked', taskId, !originalTask.isChecked, { context: { userId }, }); - const updatedTask = TasksCollection.findOne(taskId); + const updatedTask = await TasksCollection.findOneAsync(taskId); assert.notEqual(updatedTask.isChecked, originalTask.isChecked); }); - it('can insert new tasks', () => { + it('can insert new tasks', async () => { const text = 'New Task'; mockMethodCall('tasks.insert', text, { context: { userId }, }); - const tasks = TasksCollection.find({}).fetch(); + const tasks = await TasksCollection.find({}).fetchAsync(); assert.equal(tasks.length, 2); assert.isTrue(tasks.some(task => task.text === text)); }); diff --git a/src/simple-todos/step11/imports/ui/App.svelte b/src/simple-todos/step11/imports/ui/App.svelte index 0b52de6..ec2bb1c 100644 --- a/src/simple-todos/step11/imports/ui/App.svelte +++ b/src/simple-todos/step11/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; let isLoading = true; @@ -22,24 +21,25 @@ if (user) { - isLoading = !handler.ready(); + isLoading = !handler.ready(); - const userFilter = { userId: user._id }; - const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; + const userFilter = { userId: user._id }; + const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = TasksCollection.find( - hideCompleted ? pendingOnlyFilter : userFilter, - { sort: { createdAt: -1 } } - ).fetch(); + getTasks = user + ? TasksCollection.find( + hideCompleted ? pendingOnlyFilter : userFilter, + { sort: { createdAt: -1 } } + ).fetchAsync() + : []; - incompleteCount = TasksCollection.find(pendingOnlyFilter).count(); - - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() + : 0; } } + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; @@ -52,7 +52,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -63,7 +67,7 @@ {user.username} 🚪 - +
    diff --git a/src/simple-todos/step11/server/main.js b/src/simple-todos/step11/server/main.js index 39d8744..7a52216 100644 --- a/src/simple-todos/step11/server/main.js +++ b/src/simple-todos/step11/server/main.js @@ -4,8 +4,8 @@ import { TasksCollection } from '/imports/db/TasksCollection'; import '/imports/api/tasksMethods'; import '/imports/api/tasksPublications'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -14,7 +14,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -24,7 +24,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', diff --git a/tutorial/simple-todos/11-testing.md b/tutorial/simple-todos/11-testing.md index bd2657d..7ac7277 100644 --- a/tutorial/simple-todos/11-testing.md +++ b/tutorial/simple-todos/11-testing.md @@ -82,9 +82,9 @@ if (Meteor.isServer) { const userId = Random.id(); let taskId; - beforeEach(() => { - TasksCollection.remove({}); - taskId = TasksCollection.insert({ + beforeEach(async () => { + await TasksCollection.removeAsync({}); + taskId = await TasksCollection.insertAsync({ text: 'Test Task', createdAt: new Date(), userId, @@ -130,11 +130,12 @@ if (Meteor.isServer) { }); }); - it('can delete owned task', () => { + it('can delete owned task', async () => { mockMethodCall('tasks.remove', taskId, { context: { userId } }); - assert.equal(TasksCollection.find().count(), 0); + assert.equal(await TasksCollection.find().countAsync(), 0); }); + }); }); } @@ -162,53 +163,53 @@ if (Meteor.isServer) { const userId = Random.id(); let taskId; - beforeEach(() => { - TasksCollection.remove({}); - taskId = TasksCollection.insert({ + beforeEach(async () => { + await TasksCollection.removeAsync({}); + taskId = await TasksCollection.insertAsync({ text: 'Test Task', createdAt: new Date(), userId, }); }); - it('can delete owned task', () => { + it('can delete owned task', async () => { mockMethodCall('tasks.remove', taskId, { context: { userId } }); - assert.equal(TasksCollection.find().count(), 0); + assert.equal(await TasksCollection.find().countAsync(), 0); }); - it(`can't delete task without an user authenticated`, () => { + it("can't delete task without an user authenticated", async () => { const fn = () => mockMethodCall('tasks.remove', taskId); assert.throw(fn, /Not authorized/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it(`can't delete task from another owner`, () => { + it("can't delete task from another owner", async () => { const fn = () => mockMethodCall('tasks.remove', taskId, { context: { userId: 'somebody-else-id' }, }); assert.throw(fn, /Access denied/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it('can change the status of a task', () => { - const originalTask = TasksCollection.findOne(taskId); + it('can change the status of a task', async () => { + const originalTask = await TasksCollection.findOneAsync(taskId); mockMethodCall('tasks.setIsChecked', taskId, !originalTask.isChecked, { context: { userId }, }); - const updatedTask = TasksCollection.findOne(taskId); + const updatedTask = await TasksCollection.findOneAsync(taskId); assert.notEqual(updatedTask.isChecked, originalTask.isChecked); }); - it('can insert new tasks', () => { + it('can insert new tasks', async () => { const text = 'New Task'; mockMethodCall('tasks.insert', text, { context: { userId }, }); - const tasks = TasksCollection.find({}).fetch(); + const tasks = await TasksCollection.find({}).fetchAsync(); assert.equal(tasks.length, 2); assert.isTrue(tasks.some(task => task.text === text)); }); @@ -216,6 +217,7 @@ if (Meteor.isServer) { }); } + ``` If you run the test command again or left it running in watch mode before, you should see the following output: From c43c5250bccd54464d4e7d7dd1cd8d012fe8edb1 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:30:48 -0300 Subject: [PATCH 11/15] chore: updated step12 --- .../step12/imports/api/tasksMethods.js | 16 +++--- .../step12/imports/api/tasksMethods.tests.js | 28 +++++----- src/simple-todos/step12/imports/ui/App.svelte | 55 +++++++++++-------- src/simple-todos/step12/server/main.js | 8 +-- 4 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/simple-todos/step12/imports/api/tasksMethods.js b/src/simple-todos/step12/imports/api/tasksMethods.js index b1ddc18..10f8aa6 100644 --- a/src/simple-todos/step12/imports/api/tasksMethods.js +++ b/src/simple-todos/step12/imports/api/tasksMethods.js @@ -3,37 +3,37 @@ import { check } from 'meteor/check'; import { TasksCollection } from '../db/TasksCollection'; Meteor.methods({ - 'tasks.insert'(text) { + async 'tasks.insert'(text) { check(text, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - TasksCollection.insert({ + await TasksCollection.insertAsync({ text, createdAt: new Date(), userId: this.userId, }); }, - 'tasks.remove'(taskId) { + async 'tasks.remove'(taskId) { check(taskId, String); if (!this.userId) { throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.remove(taskId); + await TasksCollection.remove(taskId); }, - 'tasks.setIsChecked'(taskId, isChecked) { + async 'tasks.setIsChecked'(taskId, isChecked) { check(taskId, String); check(isChecked, Boolean); @@ -41,13 +41,13 @@ Meteor.methods({ throw new Meteor.Error('Not authorized.'); } - const task = TasksCollection.findOne({ _id: taskId, userId: this.userId }); + const task = await TasksCollection.findOneAsync({ _id: taskId, userId: this.userId }); if (!task) { throw new Meteor.Error('Access denied.'); } - TasksCollection.update(taskId, { + await TasksCollection.updateAsync(taskId, { $set: { isChecked, }, diff --git a/src/simple-todos/step12/imports/api/tasksMethods.tests.js b/src/simple-todos/step12/imports/api/tasksMethods.tests.js index 953269b..e382e79 100644 --- a/src/simple-todos/step12/imports/api/tasksMethods.tests.js +++ b/src/simple-todos/step12/imports/api/tasksMethods.tests.js @@ -11,53 +11,53 @@ if (Meteor.isServer) { const userId = Random.id(); let taskId; - beforeEach(() => { - TasksCollection.remove({}); - taskId = TasksCollection.insert({ + beforeEach(async () => { + await TasksCollection.removeAsync({}); + taskId = await TasksCollection.insertAsync({ text: 'Test Task', createdAt: new Date(), userId, }); }); - it('can delete owned task', () => { + it('can delete owned task', async () => { mockMethodCall('tasks.remove', taskId, { context: { userId } }); - assert.equal(TasksCollection.find().count(), 0); + assert.equal(await TasksCollection.find().countAsync(), 0); }); - it("can't delete task without an user authenticated", () => { + it("can't delete task without an user authenticated", async () => { const fn = () => mockMethodCall('tasks.remove', taskId); assert.throw(fn, /Not authorized/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it("can't delete task from another owner", () => { + it("can't delete task from another owner", async () => { const fn = () => mockMethodCall('tasks.remove', taskId, { context: { userId: 'somebody-else-id' }, }); assert.throw(fn, /Access denied/); - assert.equal(TasksCollection.find().count(), 1); + assert.equal(await TasksCollection.find().countAsync(), 1); }); - it('can change the status of a task', () => { - const originalTask = TasksCollection.findOne(taskId); + it('can change the status of a task', async () => { + const originalTask = await TasksCollection.findOneAsync(taskId); mockMethodCall('tasks.setIsChecked', taskId, !originalTask.isChecked, { context: { userId }, }); - const updatedTask = TasksCollection.findOne(taskId); + const updatedTask = await TasksCollection.findOneAsync(taskId); assert.notEqual(updatedTask.isChecked, originalTask.isChecked); }); - it('can insert new tasks', () => { + it('can insert new tasks', async () => { const text = 'New Task'; mockMethodCall('tasks.insert', text, { context: { userId }, }); - const tasks = TasksCollection.find({}).fetch(); + const tasks = await TasksCollection.find({}).fetchAsync(); assert.equal(tasks.length, 2); assert.isTrue(tasks.some(task => task.text === text)); }); diff --git a/src/simple-todos/step12/imports/ui/App.svelte b/src/simple-todos/step12/imports/ui/App.svelte index 0b52de6..ec2bb1c 100644 --- a/src/simple-todos/step12/imports/ui/App.svelte +++ b/src/simple-todos/step12/imports/ui/App.svelte @@ -10,9 +10,8 @@ const hideCompletedFilter = { isChecked: { $ne: true } }; - let incompleteCount; - let pendingTasksTitle = ''; - let tasks = []; + let getTasks; + let getCount; let user = null; let isLoading = true; @@ -22,24 +21,25 @@ if (user) { - isLoading = !handler.ready(); + isLoading = !handler.ready(); - const userFilter = { userId: user._id }; - const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; + const userFilter = { userId: user._id }; + const pendingOnlyFilter = { ...hideCompletedFilter, ...userFilter }; - tasks = TasksCollection.find( - hideCompleted ? pendingOnlyFilter : userFilter, - { sort: { createdAt: -1 } } - ).fetch(); + getTasks = user + ? TasksCollection.find( + hideCompleted ? pendingOnlyFilter : userFilter, + { sort: { createdAt: -1 } } + ).fetchAsync() + : []; - incompleteCount = TasksCollection.find(pendingOnlyFilter).count(); - - pendingTasksTitle = `${ - incompleteCount ? ` (${incompleteCount})` : '' - }`; + getCount = user + ? TasksCollection.find(pendingOnlyFilter).countAsync() + : 0; } } + const pendingTitle = (count) => `${count ? ` (${count})` : ''}`; const setHideCompleted = value => { hideCompleted = value; @@ -52,7 +52,11 @@
    -

    📝️ To Do List {pendingTasksTitle}

    + {#await getCount} +

    📝️ To Do List (...)

    + {:then count} +

    📝️ To Do List {pendingTitle(count)}

    + {/await}
    @@ -63,7 +67,7 @@ {user.username} 🚪 - +
    diff --git a/src/simple-todos/step12/server/main.js b/src/simple-todos/step12/server/main.js index 39d8744..7a52216 100644 --- a/src/simple-todos/step12/server/main.js +++ b/src/simple-todos/step12/server/main.js @@ -4,8 +4,8 @@ import { TasksCollection } from '/imports/db/TasksCollection'; import '/imports/api/tasksMethods'; import '/imports/api/tasksPublications'; -const insertTask = (taskText, user) => - TasksCollection.insert({ +const insertTask = async (taskText, user) => + await TasksCollection.insertAsync({ text: taskText, userId: user._id, createdAt: new Date(), @@ -14,7 +14,7 @@ const insertTask = (taskText, user) => const SEED_USERNAME = 'meteorite'; const SEED_PASSWORD = 'password'; -Meteor.startup(() => { +Meteor.startup(async () => { if (!Accounts.findUserByUsername(SEED_USERNAME)) { Accounts.createUser({ username: SEED_USERNAME, @@ -24,7 +24,7 @@ Meteor.startup(() => { const user = Accounts.findUserByUsername(SEED_USERNAME); - if (TasksCollection.find().count() === 0) { + if ( await TasksCollection.find().countAsync() === 0) { [ 'First Task', 'Second Task', From eaa14bb3865ad2a6932d535e57a450b40867a63e Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:31:09 -0300 Subject: [PATCH 12/15] chore: updated change log featuring new Mongo API --- tutorial/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tutorial/changelog.md b/tutorial/changelog.md index fdd9b88..6a9e0bf 100644 --- a/tutorial/changelog.md +++ b/tutorial/changelog.md @@ -1,6 +1,8 @@ --- title: Changelog --- +v1.2 - 05/09/2022 +- Added Adjusted tutorial to use Mongo Async API. v1.1 - 16/05/2022 - Tutorial Review. From b2c7380f975498bb37127b0750bb9bfa67b48b8b Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:31:32 -0300 Subject: [PATCH 13/15] Revert "chore: updated change log featuring new Mongo API" This reverts commit eaa14bb3865ad2a6932d535e57a450b40867a63e. --- tutorial/changelog.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/tutorial/changelog.md b/tutorial/changelog.md index 6a9e0bf..fdd9b88 100644 --- a/tutorial/changelog.md +++ b/tutorial/changelog.md @@ -1,8 +1,6 @@ --- title: Changelog --- -v1.2 - 05/09/2022 -- Added Adjusted tutorial to use Mongo Async API. v1.1 - 16/05/2022 - Tutorial Review. From f2ad5a0eda056c959b7b340451953334e9a47634 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:31:46 -0300 Subject: [PATCH 14/15] Revert "Revert "chore: updated change log featuring new Mongo API"" This reverts commit b2c7380f975498bb37127b0750bb9bfa67b48b8b. --- tutorial/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tutorial/changelog.md b/tutorial/changelog.md index fdd9b88..6a9e0bf 100644 --- a/tutorial/changelog.md +++ b/tutorial/changelog.md @@ -1,6 +1,8 @@ --- title: Changelog --- +v1.2 - 05/09/2022 +- Added Adjusted tutorial to use Mongo Async API. v1.1 - 16/05/2022 - Tutorial Review. From 2a4cfa8f8b3c561021f7fb8f565d25733f6aca66 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 8 Sep 2022 09:20:40 -0300 Subject: [PATCH 15/15] fix: adressed comments --- tutorial/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/changelog.md b/tutorial/changelog.md index 6a9e0bf..06b3d39 100644 --- a/tutorial/changelog.md +++ b/tutorial/changelog.md @@ -2,7 +2,7 @@ title: Changelog --- v1.2 - 05/09/2022 -- Added Adjusted tutorial to use Mongo Async API. +- Adjusted tutorial to use Mongo Async API. v1.1 - 16/05/2022 - Tutorial Review.