Skip to content

Instantly share code, notes, and snippets.

@ravisiyer
Last active March 9, 2024 13:48
Show Gist options
  • Save ravisiyer/0a5c18647eb9bfe9240ba42b4ea0c4a6 to your computer and use it in GitHub Desktop.
Save ravisiyer/0a5c18647eb9bfe9240ba42b4ea0c4a6 to your computer and use it in GitHub Desktop.
Blogger: Creating lists or indented text within ordered lists optionally with additional text after nested list - HTML code
<p>
This post is based on a detailed note-cum-log I wrote as I was creating the
Node Express &amp; MongoDB tutorial Blog API. I think it may be useful for
others who are using the
<a href="https://raviswdev.blogspot.com/2024/01/roadmap-to-learning-full-stack-web.html">roadmap to full stack web development</a>
that I have provided.
</p>
<p>
The steps I followed to successfully create a Node Express &amp; Mongo DB
tutorial Blog API which worked with the React tutorial Blog application after
some small changes to the latter, are given below:
</p>
<p></p>
<ol style="text-align: left;">
<li>
I created a project with only the latest version files of my coding
variation of the Node Express tutorial's 1st project (TASK MANAGER). I
tested it and it was working. I saved this project excluding node_modules as
a separate folder which can act as a project starter folder/boilerplate for
***simple (tutorial grade)*** Node Express backends. Note that this project
includes a Mongoose, mongoDB, morgan logger, asyncwrapper, custom error
handling etc. are all included. However, the code involved is typically not
long or complex, except for asyncwrapper (which I find to be complex). But
then asyncwrapper perhaps can simply be used as is, even if one only
understands how to use it but not how exactly it works.
</li>
<li>
Refactored the starter project code to use post/posts/Post instead of
person/people/Person, and (post) title instead of name. VSCode's feature of
search and replace in files in project was very helpful for this task,
though a few had to be handled manually. Also had to change filenames in
project from person to post. Was able to refactor the frontend code too
though it required more manual work but not too much work. MongoDB Database
is still "People-Manager" but has two collections: people and posts. The
refactored project data uses posts. I think creating a new MongoDB database
like "Blog" and having posts collection within it may involve simple step in
MongoDB to create the "Blog" database and in .env file in the project, I
will need to use "Blog" instead of "People-Manager" for MONGO_URI env. var.
Right now creating new database "Blog" is NOT a priority.
</li>
<li>
Added to mongoose models schema (model/post.js) to bring it in sync with
data/db.json of cawv-1201-blog-easyPeasy React project. The new schema is as
follows:
</li>
<pre style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"> const schema = new mongoose.Schema({
title: {
type: String,
required: [true, "title has to be specified"],
trim: true,
},
body: {
type: String,
},
datetime: { type: Date, default: Date.now },
});
</pre>
With only above schema change, the app is working, including the front-end
even though body property is not created when new posts are created. datetime
property is created due to above default specification.
<li>
To add body and datetime functionality to app code, only controllers/post.js
had to be modified. Within post.js, getPosts, getPost and deletePost did not
have to be modified. Only createPost and updatePost had to be modified. Note
that the app does not support patch API now. Updates are done through put
API (routes/post.js sets up updatePost method in controllers/post.js as the
function to 'handle' put API). Following changes were made to createPost (in
controllers/post.js):
</li>
<pre style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"> const { title, body, datetime } = req.body;
...
const post = await Post.create({
title: title,
body: body,
datetime: datetime,
});
</pre>
Note that earlier code for the above, did not have body and datetime
properties. That was the change made. Tried out post API request through
Postman, and it worked. MongoDB website shows it and Postman Get (all posts)
shows it (body added via post is shown). A test case was if only title is
provided in Postman post request. The API app adds a new document with _id,
title and datetime properties (datetime set to current datetime) but without
body property. Looking up the documentation to check if this is how
Mongoose/MongoDB are supposed to work turned out to be a time-consuming task
which I will put up as a separate post.
<li>Following changes were made to updatePost (in controllers/post.js):</li>
<pre style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"> const post = await Post.findOneAndUpdate(
{ _id: postID },
{ title: req.body.title, body: req.body.body, datetime: req.body.datetime },
{ new: true, runValidators: true }
);
</pre>
Note that earlier code for the above, did not have body and datetime
properties. That was the change made. Tested through Postman and it worked.
<li>
Next task was to modify the React Blog app. to use above Node Express API
instead of json-server. Used source code of my code variation of the React
tutorial easy-peasy project as the base. Ran 'npm install' to create
node_modules. Removed not needed packages from it using uninstall. Got the
React app to run and it worked as expected using json-server data. Changes
to be made in refactoring this app to use Node Express API:
</li>
<ul style="text-align: left;">
<li>
Blog API returns posts as data property in return object whereas JSON
server returns posts directly. So React app code will have to refer to
axios Response.data.data to get the posts or post data.
</li>
<li>
The id property of JSON server version has to be replaced by _id property
of Blog API version
</li>
<li>patch API usage has to be changed to use put API</li>
<li>API url has to be changed to refer to Blog API</li>
</ul>
<li>
Made some of the above changes. Ran app. React 'npm start' prompted for port
change from 4000 as 4000 was being used (by Express API server). I said yes
and React used port 4001. Got this error (on browser console), "Access to
XMLHttpRequest at 'http://localhost:4000/api/posts/' from origin
'http://localhost:4001' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested resource."
which resulted in further errors. My useEffects code in app.js of React app
had some bugs related to error handling. Fixed those bugs and later
refactored the useEffects code to make it cleaner. Am not including those
details here as they are not related to this post's topic.
</li>
<li>
Got the solution for the CORS error from
<a href="https://www.geeksforgeeks.org/how-to-deal-with-cors-error-in-express-node-js-project/">https://www.geeksforgeeks.org/how-to-deal-with-cors-error-in-express-node-js-project/</a>
. The added code to app.js in express API that fixed it (with some earlier
code for context):
</li>
<pre style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"> const express = require("express");
const cors = require("cors");
const app = express();
// CORS is enabled for all origins
app.use(cors());
</pre>
Ran 'npm install cors' and then ran the app. The CORS error did not come up.
<li>
The React app code expects post objects to have all properties (including
body). So added a default of "" for body in model/post.js in Express API.
Then React app was able to retrieve the two posts from express API. Viewing
post was OK.
</li>
<li>
Got React app's new post to work quite easily (just one code line had not
been refactored; to use axiosResponse.data.data instead of
axiosResponse.data).
</li>
<li>React app's delete post worked straight away.</li>
<li>
React app's edit post needed code to be changed to use put instead of patch
and some other refactoring (to use axiosResponse.data.data instead of
axiosResponse.data). Then React app's edit post functionality also was
working.
</li>
<li>
Now all functionality of React app was working with Node Express API. I then
dropped the json-server package and data directory from the project. Also
cleaned up some commented old code. Tested app again and it was working.
</li>
</ol>
<div>
That finished the task of creating Node Express &amp; MongoDB tutorial Blog
API and refactoring the React tutorial blog app to work with it.
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment