CRUDing with JSX
Building a CMS
Having now built queries for different ways to view the data (the R of CRUDing), we will next add the ability to create a new document, update it and delete it. This will form a seperate part of the web application called a CMS (Content Management System).
Later we'll secure with a login/passoword but for now we'll just create the functionality. The controller login will be very similar to the queries already built for the API.
Setting Up a CMS Home Page
To keep code manageable create a new route file of src/routes/cmsroutes.ts
.
Add a GET
call to the homepage:
The route will call the same getAllData()
method used in a previous file but we will send it a different title.
Add this new router file to the entry index.ts
file:
By adding app.use("/cms", cmsroutes)
all paths in the cmsroutes.ts
can be relative ie /
will reference localhost:3000/cms/ and /edit
will reference localhost:3000/edit.
There is already a view set up at src/views/cms.ejs
that will be rendered by a request of
localhost:3000/cms/. This page lists all the films, and we will later add links so that data can be edited or deleted.
Notice that the view does contain an "Add New" link from where we will be able to add a new document to the collection.
Adding a GET
and POST
Route for Inserting a Document
Notice there is a view set up at src/view/insert.ejs
. This holds a HTML form with fields that match those in the model.
To add a new document, a user will initially navigate to this view via a GET
call, as such this requires a simple route to be added of:
The GET
call will render the src/view/insert.ejs
view. The HTML form inside the view has a method
of POST
set. As such when the form is submitted a POST
request will be made to the application which will send the user inputted data through with the request.
This is done through the request.body
. In an Express application, when a client makes an HTTP POST
request and includes data in the body of the request, the server can access that data through the request.body
property. The request object represents the incoming HTTP request, and the body property contains the parsed body of the request.
Add the POST
request with:
If the call to createData()
method is successful, the user is redirected via the response objects res.redirect
method. In this case the user is redirect back to localhost:3000/cms/.
Adding a Create Method in the CMS Controller
With the routes set up we now need to create the createData()
method.
Again, to keep things tidy we'll create a new controller specifically for the CMS. Create a file src/controller/cmscontroller
and add the following:
First we import the Film
calls and IFIlm
interface from the src/models/Film
module.
The createData
asynchronous function takes a parameter named data
, which is of type Partial<IFilm>
. The Partial<T>
type in TypeScript allows properties of T
to be optional, meaning not all properties of IFilm
need to be provided. The function then calls the create()
method to create a new document which is returned if done successfully.
Note: Ensure you import the cmscontroller
into the route file.
You should now be able to add a new document/film to the collection.
Adding a GET
and POST
Route for Editing a Document
For editing we will require to have two queries, one to get the current values and one to execute anhy update.
As such we will again need two routes, a GET
call to show the edit page and a POST call to update the data. Notice with the GET
call we will need to query the database to get the current document. Again, we already have a function for this in the src/controllers/controller
file called getDataById
so we'll reuse this. Add the following to src/routes/cmsroutes.ts
To arrive at this page edit the src/views/cms.ejs
to make the text 'edit' a hyperlink that passes the id
as a URL Parameter
When the link is following the URL parameter is used in the getDataById
to retrieve the data for film. In the view at src/views/edit.ejs
see how the values are used to populate the HTML form with the correct values.
Note: In the view the id
for the document is set as a hidden field so that we don't need to sent it in the URL when actually editing the page.
Next we need to add the POST
request. You might expect a PUT
request here inline with RESTful techniques, however in HTML forms the action
method only supports GET
and POST
. We could use some Javascript to get around this but for our purposes it will be easier to just use a POST
request for the edit form.
Add the following router:
When the POST
call is made the request object body
property is again used to send the data. We send the id
and the entire body
as two values to make the retrieval of the id
easy for the controller.
If the call to updateData
is successful the user if redirect with res.redirect("/cms/")
as done with the insert example.
Adding a Update Method in the CMS Controller
Next add the controller method for the update.
The updateData
function expects an id
and data
, a partial from the HTML form. From these a findByIdAndUpdate
query is run.
Note: Ensure you export the new updateData
method from the controller.
The CMS should now allow the editing of documents.
Adding the GET
and POST
Delete Route
To add the delete funcionality a similar set up is required. First we need a GET
to ensure the correct record is removed. Then a POST
route to call a delete method (again because of the limitions of the HTML form method).
Set up the GET
route as:
To link to the delete page edit the src/views/cms.ejs
to make the text 'delete' a hyperlink that passes the id
as a URL Parameter
The GET
call will use the src/views/delete.ejs
to generate a page where the user can check to see if this the correct document to delete. They can choose to keep the document by simply navigating away, alternatively they can make a POST
call to delete the record by submitting the form with a hidden field value for the id
.
Set up the POST
route as:
Again, if successful the user is redirected to the CMS homepage.
Building the Delete Controller
The delete controller will appear as:
The deleteData
method receives the id
of the document to remove from the collection doing so via convenient Mongoose findByIdAndDelete
Note: Ensure you export the new deleteData
method from the controller.
Users should now be able to add, update and delete documents.
What we need to do next is limit who can do this.