From bd448e90e435f8fa818d7ef0de7db095971e6c58 Mon Sep 17 00:00:00 2001 From: AbelGAlem Date: Wed, 19 Nov 2025 20:10:58 +0200 Subject: [PATCH 1/5] Use the findByIdAndUpdate method and avoid nested promises when updating a note --- src/content/3/en/part3c.md | 54 +++++++++++--------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/content/3/en/part3c.md b/src/content/3/en/part3c.md index 1b9651a9108..fb1c7edf8f6 100644 --- a/src/content/3/en/part3c.md +++ b/src/content/3/en/part3c.md @@ -887,49 +887,27 @@ In both of the "successful" cases of deleting a resource, the backend responds w Let's implement the functionality to update a single note, allowing the importance of the note to be changed. The note updating is done as follows: ```js -app.put('/api/notes/:id', (request, response, next) => { - const { content, important } = request.body - - Note.findById(request.params.id) - .then(note => { - if (!note) { - return response.status(404).end() - } - - note.content = content - note.important = important - - return note.save().then((updatedNote) => { - response.json(updatedNote) - }) - }) - .catch(error => next(error)) +app.put("/api/notes/:id", (request, response, next) => { + const {content, important} = request.body + + Person.findByIdAndUpdate( + request.params.id, + {note: content, important: important}, + {new: true} + ).then(updatedNote => { + if(!updatedNote){ + return response.status(404).end() + } + return response.json(updatedNote); + }).catch(error => next(error)) }) ``` -The note to be updated is first fetched from the database using the _findById_ method. If no object is found in the database with the given id, the value of the variable _note_ is _null_, and the query responds with the status code 404 Not Found. - -If an object with the given id is found, its _content_ and _important_ fields are updated with the data provided in the request, and the modified note is saved to the database using the _save()_ method. The HTTP request responds by sending the updated note in the response. +The note to be updated is modified directly in the database using the findByIdAndUpdate method. If no object is found in the database with the given id, the value of the variable updatedNote is null, and the query responds with the status code 404 Not Found. -One notable point is that the code now has nested promises, meaning that within the outer _.then_ method, another [promise chain](https://javascript.info/promise-chaining) is defined: - -```js - .then(note => { - if (!note) { - return response.status(404).end() - } - - note.content = content - note.important = important - - // highlight-start - return note.save().then((updatedNote) => { - response.json(updatedNote) - }) - // highlight-end -``` +If an object with the given id is found, its content and important fields are updated with the data provided in the request, and the database returns the updated note. The HTTP request responds by sending this updated note in the response. -Usually, this is not recommended because it can make the code difficult to read. In this case, however, the solution works because it ensures that the _.then_ block following the _save()_ method is only executed if a note with the given id is found in the database and the _save()_ method is called. In the fourth part of the course, we will explore the async/await syntax, which offers an easier and clearer way to handle such situations. +In the options given to findByIdAndUpdate, the value of the new field is set to true. This tells Mongoose to return the updated document instead of the original version from before the update. After testing the backend directly with Postman or the VS Code REST client, we can verify that it seems to work. The frontend also appears to work with the backend using the database. From d2b213286dda3d40a6e056e20541d0b6aaad230f Mon Sep 17 00:00:00 2001 From: AbelGAlem Date: Mon, 22 Dec 2025 19:18:10 +0200 Subject: [PATCH 2/5] test: assert deletion by id instead of content --- src/content/4/en/part4b.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/4/en/part4b.md b/src/content/4/en/part4b.md index ea3871ad4f6..b324df36f71 100644 --- a/src/content/4/en/part4b.md +++ b/src/content/4/en/part4b.md @@ -794,8 +794,8 @@ test('a note can be deleted', async () => { const notesAtEnd = await helper.notesInDb() - const contents = notesAtEnd.map(n => n.content) - assert(!contents.includes(noteToDelete.content)) + const ids = notesAtEnd.map(n => n.id) + assert(!ids.includes(noteToDelete.id)) assert.strictEqual(notesAtEnd.length, helper.initialNotes.length - 1) }) From 4b1a795a689ab517b2be2961e74149ba7aaf9584 Mon Sep 17 00:00:00 2001 From: AbelGAlem Date: Mon, 22 Dec 2025 19:18:10 +0200 Subject: [PATCH 3/5] test: assert deletion by id instead of content --- src/content/4/en/part4b.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/4/en/part4b.md b/src/content/4/en/part4b.md index ea3871ad4f6..b324df36f71 100644 --- a/src/content/4/en/part4b.md +++ b/src/content/4/en/part4b.md @@ -794,8 +794,8 @@ test('a note can be deleted', async () => { const notesAtEnd = await helper.notesInDb() - const contents = notesAtEnd.map(n => n.content) - assert(!contents.includes(noteToDelete.content)) + const ids = notesAtEnd.map(n => n.id) + assert(!ids.includes(noteToDelete.id)) assert.strictEqual(notesAtEnd.length, helper.initialNotes.length - 1) }) From 86407bac86c0c55c160c2a10915d92fd8c9bf6da Mon Sep 17 00:00:00 2001 From: AbelGAlem Date: Sun, 4 Jan 2026 12:20:27 +0200 Subject: [PATCH 4/5] test: verify note deletion by id instead of content --- src/content/4/en/part4b.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/4/en/part4b.md b/src/content/4/en/part4b.md index b324df36f71..0a9e777efc4 100644 --- a/src/content/4/en/part4b.md +++ b/src/content/4/en/part4b.md @@ -1087,8 +1087,8 @@ describe('when there is initially some notes saved', () => { const notesAtEnd = await helper.notesInDb() - const contents = notesAtEnd.map(n => n.content) - assert(!contents.includes(noteToDelete.content)) + const ids = notesAtEnd.map(n => n.id) + assert(!ids.includes(noteToDelete.id)) assert.strictEqual(notesAtEnd.length, helper.initialNotes.length - 1) }) From 04b7122d325adacd98c4c97a83b41f993a2d6d24 Mon Sep 17 00:00:00 2001 From: AbelGAlem Date: Sun, 4 Jan 2026 12:30:10 +0200 Subject: [PATCH 5/5] Revert "Use the findByIdAndUpdate method and avoid nested promises when updating a note" This reverts commit bd448e90e435f8fa818d7ef0de7db095971e6c58. --- src/content/3/en/part3c.md | 54 +++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/src/content/3/en/part3c.md b/src/content/3/en/part3c.md index fb1c7edf8f6..1b9651a9108 100644 --- a/src/content/3/en/part3c.md +++ b/src/content/3/en/part3c.md @@ -887,27 +887,49 @@ In both of the "successful" cases of deleting a resource, the backend responds w Let's implement the functionality to update a single note, allowing the importance of the note to be changed. The note updating is done as follows: ```js -app.put("/api/notes/:id", (request, response, next) => { - const {content, important} = request.body - - Person.findByIdAndUpdate( - request.params.id, - {note: content, important: important}, - {new: true} - ).then(updatedNote => { - if(!updatedNote){ - return response.status(404).end() - } - return response.json(updatedNote); - }).catch(error => next(error)) +app.put('/api/notes/:id', (request, response, next) => { + const { content, important } = request.body + + Note.findById(request.params.id) + .then(note => { + if (!note) { + return response.status(404).end() + } + + note.content = content + note.important = important + + return note.save().then((updatedNote) => { + response.json(updatedNote) + }) + }) + .catch(error => next(error)) }) ``` -The note to be updated is modified directly in the database using the findByIdAndUpdate method. If no object is found in the database with the given id, the value of the variable updatedNote is null, and the query responds with the status code 404 Not Found. +The note to be updated is first fetched from the database using the _findById_ method. If no object is found in the database with the given id, the value of the variable _note_ is _null_, and the query responds with the status code 404 Not Found. + +If an object with the given id is found, its _content_ and _important_ fields are updated with the data provided in the request, and the modified note is saved to the database using the _save()_ method. The HTTP request responds by sending the updated note in the response. -If an object with the given id is found, its content and important fields are updated with the data provided in the request, and the database returns the updated note. The HTTP request responds by sending this updated note in the response. +One notable point is that the code now has nested promises, meaning that within the outer _.then_ method, another [promise chain](https://javascript.info/promise-chaining) is defined: + +```js + .then(note => { + if (!note) { + return response.status(404).end() + } + + note.content = content + note.important = important + + // highlight-start + return note.save().then((updatedNote) => { + response.json(updatedNote) + }) + // highlight-end +``` -In the options given to findByIdAndUpdate, the value of the new field is set to true. This tells Mongoose to return the updated document instead of the original version from before the update. +Usually, this is not recommended because it can make the code difficult to read. In this case, however, the solution works because it ensures that the _.then_ block following the _save()_ method is only executed if a note with the given id is found in the database and the _save()_ method is called. In the fourth part of the course, we will explore the async/await syntax, which offers an easier and clearer way to handle such situations. After testing the backend directly with Postman or the VS Code REST client, we can verify that it seems to work. The frontend also appears to work with the backend using the database.