MVC | KonMari Your Code
Published: 2024-03-11 15:36:35

So you're learning full-stack JavaScript and starting to get into the backend of things.  Working with Node, Express, and MongoDb and the server.js file is a mile long and full of spaghetti.

## Enter MVC | Model View Controller
MVC is both the workflow of how your full-stack program handles requests and how you organize your files based on that flow. I know starting with a flowchart image probably doesn't make sense, but we will need this for reference. There is also a TL;DR down at the bottom if deep-diving isn't your thing.

![MVC Flowchart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u30s0mem1zddsd5asqk9.png)

## Let's Break it Down
In my opinion, this should be 'Routes, Controller, Model, View' instead of 'Model View Controller' and as I go over the process below you might see why too.

Starting with the user, the happy green smiley, who wants to visit a website with a to-do list. When this user goes to the website they'll be sending a route request which has a bunch of different information like where they want to go and what they want to do. For our purpose today, the user is going to be requesting on the `/todos` route.

Here's a peek at the code so we can see what will happen.

### server.js
 
![server.js code file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7ulydol9rjai3cg6cx4.png)

Aaah, where do we begin?! Realistically we only need to look at this piece of code for now.

![code snippet from server.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9iw29nhwviw7owv9bji.png)

So when a user sends requests on the `'/todos'` route, our program will see that and fire them off to the `todoRoutes`.

### Routes

Now why would you want to have a separate route file, even if it's not a part of traditional MVC? Well, it adds a level of abstraction between the different steps in the workflow, breaking it down into smaller bite-sized pieces. Without routes having their own separate place they would be bundled in with the Controller and you'll see why combining these can make things confusing.

Now, back to the `todosRoutes`...

![todoRoutes Code File](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2aw56t2m5bk1fcto0f6u.png)

You can see the `todosRoutes` has instructions on how to handle different requests. Depending on what route and request type it'll hand you off to a different controller.

![code snippet from todoRoutes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp8b7tjgicoa1nzqzke8.png)

This is a `get` request on the `/todos` `/` root route, which will send us over to the `todosController` and look at `getTodos` for what to do next.

### Controller
This is where the ✨ MVC magic ✨ starts to happen and the different aspects of the Model View Controller come into play.

The Controller does two big things; interacts with the database through Models and renders the webpage from Views. 

![todosController code file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljr0hlqgdw7s3hlboxpe.png)

Let's take a step back... could you imagine this Controller with the routes added in too? What if you have ten-fold the routes and controller modules... this is why separating the steps into their own places *just makes sense*! If you need to find something specific you know where to look or you can even follow the code around the different files because they leave breadcrumbs on where to look next.

So we're in the `todosController` and need to look at the `getTodos`. 

![getTodos code snippet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/krxqwfg29sbd1la1cr14.png)

The `getTodos` Controller uses the `Todo` Model to gather all of the documents in the database, and it also counts all the documents where `completed: false`. With the database information gathered through the Model, the Controller then uses the Views to render the `todos.ejs` file for the user.


![Confused Gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rawkp4t3gajecyilo8h.gif)

I know... I know.  It's time to get into the details.


### Models
The `Todo` Model we'll be looking at includes a Mongoose schema. Now you may be asking what a schema is... In simple terms, it is like a blueprint for creating documents in MongoDB. It defines the structure of the documents, including the types of data that can be stored in each field, default values, and how the data should be validated. Think of it as a template that tells MongoDB what kind of data to expect and how to handle it.

![todoModel and Schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52ave68fw5ddbe65zqmh.png)

So looking at this Model and the schema within, you can see that our documents in the database collection have two properties: `todo` and `completed` and each of these has a defined type and if they're required. This is a great way to know the kind of data we're working with and what can be submitted to and requested from the database, especially if you don't have access to the database yourself.

![code snipppet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0fkoytu0exoynz5gxxm.png)

When a document in the database matches the format stated within the schema it will be associated with the Model, which is important when we look at the Controller.  You can see that the `find()` and `countDocuments()` work with the `Todo` Model to get documents that match the schema from the database.

![code snippet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqlwrr41g03iw6rcidg0.png)

And once we have that information from the Database we use it to render the `todos.ejs` from our Views.

### Views

This is where we render what the user will see and interact with on their end. We inject the documents from the database (which were gathered through the Model), this allows the user to interact with the data displayed in the DOM. The Views file doesn't actually know where that data came from or how it was processed; it just displays what it's instructed by the Controller.

![code snippet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ehgmm5udbc2v9u0stlo.png)

Above is a code snippet from the `todosController` that renders the View's `todos.ejs` and passes in the database information with `todos` and `left` variables.

![EJS code file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac8umozw0bfv1dz0fcjg.png)

This is the Views `todos.ejs` file, you can see here we are generating an unordered list with the database information that was passed in by the `todosController` with the `todos` variable. It uses the document's ID in the database to create each `<li>` and checks if it is `completed` to set the class for styling. We also use the `left` variable to create a tally of how many items are not complete.

Views are also an area where using MVC can shine. If you wanted to use a different templating engine, React, Vue, etc, all you would need to do is change the Views file. There wouldn't be a need to update any other files as it's all been abstracted from each other.

### Summary: The TL;DR

![Workflow with Directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy13af7h6nvf9tdkhs2h.png)

So to sum up the movement around this to-do application this is how it goes:

1. The user submits a request to the `/todos` route.
2. `server.js`: looks at the request and sends it to the appropriate Route.
3. `Routes`: looks at what kind of request was made and on what path it was for then sends it to the appropriate Controller.
4. `Controller`: Utilizes the Model and/or View to complete the request.
5. `Model`: Uses a schema to find the associated database documents needed by the Controller.
6. `View`: Renders the appropriate file into the DOM as instructed by the Controller. This may or may not include database documents.

MVC is a powerful design pattern that simplifies application development by setting up your code so everything is less chaotic. It separates concerns, supports scalability and maintainability, facilitates team collaboration, and offers flexibility in development and maintenance processes.

In a nutshell, Model View Controller is a friendly guide that makes coding less of a headache.