<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Mel’s web development blog ]]></title><description><![CDATA[Mel’s web development blog ]]></description><link>https://melvinlucas.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 31 Aug 2026 12:01:24 GMT</lastBuildDate><atom:link href="https://melvinlucas.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Calculate the Hidden Units in the Classifier Layer of TinyVGG]]></title><description><![CDATA[When building a custom neural network, such as the TinyVGG model, it's crucial to correctly calculate the number of hidden units that feed into the classifier layer. This step-by-step guide will walk you through the process.
Step 1: Understanding the...]]></description><link>https://melvinlucas.hashnode.dev/how-to-calculate-the-hidden-units-in-the-classifier-layer-of-tinyvgg</link><guid isPermaLink="true">https://melvinlucas.hashnode.dev/how-to-calculate-the-hidden-units-in-the-classifier-layer-of-tinyvgg</guid><category><![CDATA[Machine Learning]]></category><category><![CDATA[pytorch]]></category><dc:creator><![CDATA[Melvin Lucas]]></dc:creator><pubDate>Sat, 24 Aug 2024 21:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725182695976/884b67a4-6b23-4af4-8096-a6db6f3ba85e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When building a custom neural network, such as the TinyVGG model, it's crucial to correctly calculate the number of hidden units that feed into the classifier layer. This step-by-step guide will walk you through the process.</p>
<h3 id="heading-step-1-understanding-the-model-architecture">Step 1: Understanding the Model Architecture</h3>
<p>The TinyVGG model consists of convolutional layers followed by pooling layers, which reduce the spatial dimensions of the input. Here's the architecture we'll use:</p>
<ul>
<li><p><strong>ConvBlock 1</strong>: Two convolutional layers followed by a max-pooling layer.</p>
</li>
<li><p><strong>ConvBlock 2</strong>: Two convolutional layers followed by a max-pooling layer.</p>
</li>
<li><p><strong>Classifier</strong>: A fully connected layer that takes the flattened feature map as input and outputs the class scores.</p>
</li>
</ul>
<h3 id="heading-step-2-initial-image-dimensions">Step 2: Initial Image Dimensions</h3>
<p>First, let's define the initial image dimensions:</p>
<ul>
<li><p><code>C</code>: Number of channels (e.g., 3 for RGB images).</p>
</li>
<li><p><code>H</code>: Height of the image.</p>
</li>
<li><p><code>W</code>: Width of the image.</p>
</li>
</ul>
<h3 id="heading-step-3-define-the-tinyvgg-class">Step 3: Define the TinyVGG Class</h3>
<p>We'll start by defining the TinyVGG class, including the convolutional blocks and the classifier. The key is to calculate the size of the feature map that will be fed into the classifier.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">import</span> torch.nn <span class="hljs-keyword">as</span> nn

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TinyVGG</span>(<span class="hljs-params">nn.Module</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, input_shape: int, hidden_units: int, output_shape: int, image_size: int</span>) -&gt; <span class="hljs-keyword">None</span>:</span>
        super().__init__()
        self.image_size = image_size  <span class="hljs-comment"># Store the input image size</span>
        self.conv_block_1 = nn.Sequential(
            nn.Conv2d(in_channels=input_shape,
                      out_channels=hidden_units,
                      kernel_size=<span class="hljs-number">3</span>,
                      stride=<span class="hljs-number">1</span>,
                      padding=<span class="hljs-number">1</span>),
            nn.ReLU(),
            nn.Conv2d(in_channels=hidden_units,
                      out_channels=hidden_units,
                      kernel_size=<span class="hljs-number">3</span>,
                      stride=<span class="hljs-number">1</span>,
                      padding=<span class="hljs-number">1</span>),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=<span class="hljs-number">2</span>, stride=<span class="hljs-number">2</span>)
        )
        self.conv_block_2 = nn.Sequential(
            nn.Conv2d(hidden_units,
                      hidden_units,
                      kernel_size=<span class="hljs-number">3</span>,
                      padding=<span class="hljs-number">1</span>),
            nn.ReLU(),
            nn.Conv2d(hidden_units,
                      hidden_units,
                      kernel_size=<span class="hljs-number">3</span>,
                      padding=<span class="hljs-number">1</span>),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=<span class="hljs-number">2</span>, stride=<span class="hljs-number">2</span>)
        )

        <span class="hljs-comment"># Calculate the size after conv and pooling layers</span>
        conv_output_size = self._get_conv_output_size(image_size, hidden_units)

        self.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(in_features=conv_output_size,
                      out_features=output_shape)
        )

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_get_conv_output_size</span>(<span class="hljs-params">self, image_size, hidden_units</span>):</span>
        <span class="hljs-comment"># Calculate the size of the feature map after the conv layers</span>
        <span class="hljs-keyword">return</span> hidden_units * (image_size // <span class="hljs-number">4</span>) * (image_size // <span class="hljs-number">4</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">forward</span>(<span class="hljs-params">self, x: torch.Tensor</span>):</span>
        x = self.conv_block_1(x)
        x = self.conv_block_2(x)
        x = self.classifier(x)
        <span class="hljs-keyword">return</span> x
</code></pre>
<h3 id="heading-step-4-calculate-the-feature-map-size">Step 4: Calculate the Feature Map Size</h3>
<p>To determine the size of the feature map after the convolutional and pooling layers:</p>
<ul>
<li><p><strong>ConvBlock 1</strong>: The convolutional layers keep the height and width the same (due to padding=1), but the max-pooling layer reduces them by half.</p>
<ul>
<li><strong>Height and Width after ConvBlock 1</strong>: H/2, W/2.</li>
</ul>
</li>
<li><p><strong>ConvBlock 2</strong>: The max-pooling layer again halves the height and width.</p>
<ul>
<li><strong>Height and Width after ConvBlock 2</strong>: H/4, W/4.</li>
</ul>
</li>
</ul>
<p>Therefore, the size of the feature map that feeds into the classifier is:<br /><code>Hidden Units × (H/4) × (W/4)</code></p>
<p>Step 5: Implementing the Forward Method</p>
<p>The forward method applies the convolutional blocks and passes the result through the classifier.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">forward</span>(<span class="hljs-params">self, x: torch.Tensor</span>):</span>
    x = self.conv_block_1(x)
    x = self.conv_block_2(x)
    x = self.classifier(x)
    <span class="hljs-keyword">return</span> x
</code></pre>
<h3 id="heading-step-6-testing-the-model">Step 6: Testing the Model</h3>
<p>Finally, let's test the model with a sample input to ensure everything is working correctly.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Example usage</span>
image_size = <span class="hljs-number">64</span>  <span class="hljs-comment"># Example input image size (H=W=64)</span>
input_channels = <span class="hljs-number">3</span>  <span class="hljs-comment"># Example input image channels (C=3)</span>
hidden_units = <span class="hljs-number">16</span>
output_classes = <span class="hljs-number">10</span>

model = TinyVGG(input_shape=input_channels, hidden_units=hidden_units, output_shape=output_classes, image_size=image_size)
print(model)

<span class="hljs-comment"># Example forward pass with random data</span>
x = torch.randn((<span class="hljs-number">1</span>, input_channels, image_size, image_size))  <span class="hljs-comment"># Batch size of 1</span>
output = model(x)
print(output.shape)  <span class="hljs-comment"># Should be (1, output_classes)</span>
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>By following these steps, you can correctly calculate the number of hidden units that feed into the classifier layer of a TinyVGG model. This approach ensures that the model architecture is consistent and that the classifier receives the correct number of inputs.</p>
]]></content:encoded></item><item><title><![CDATA[Underfitting and Overfitting in Machine Learning.]]></title><description><![CDATA[What is a loss curve?


A loss curve is a graphical representation of the loss value over time during the training process of a machine-learning model. The loss value measures how well or poorly the model's predictions match the actual target values,...]]></description><link>https://melvinlucas.hashnode.dev/underfitting-and-overfitting-in-machine-learning</link><guid isPermaLink="true">https://melvinlucas.hashnode.dev/underfitting-and-overfitting-in-machine-learning</guid><dc:creator><![CDATA[Melvin Lucas]]></dc:creator><pubDate>Tue, 30 Jul 2024 10:08:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722329861162/e51a5e9d-045e-4fb5-891d-53d9cbdd6c38.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><h3 id="heading-what-is-a-loss-curve">What is a loss curve?</h3>
</li>
</ol>
<p>A loss curve is a graphical representation of the loss value over time during the training process of a machine-learning model. The loss value measures how well or poorly the model's predictions match the actual target values, with lower loss indicating better performance.</p>
<p>An ideal loss curve typically appears as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722330247275/3587982d-2a31-450c-977d-eb8d5e3d8661.png" alt class="image--center mx-auto" /></p>
<p>The plot shows a steady decrease in training loss over epochs, indicating effective learning and good data generalization.</p>
<h3 id="heading-visualization-with-loss-curves">Visualization with Loss Curves</h3>
<p>Loss curves can help identify the underfitting and overfitting of a model by providing visual indicators of the model's performance over time.</p>
<p>Underfitting occurs when a machine learning model is too simple to capture the underlying patterns in the training data, leading to poor performance on both the training data and new, unseen data.</p>
<p>Overfitting occurs when a machine learning model performs exceptionally well on the training data but fails to generalize effectively to new, unseen data.</p>
<p>The comparison of loss curves look like below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722331418605/22187f4c-7b51-4dd0-b404-668520797aa9.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Left</em> <strong>Underfitting</strong>: The training loss remains high and does not significantly decrease over epochs, indicating that the model is not learning the underlying patterns effectively.</p>
<p><em>Middle</em> <strong>Overfitting</strong>: The training loss decreases sharply while the model performs poorly on new, unseen data, indicating that it has learned the training data too well but fails to generalize.</p>
<p><em>Right</em> <strong>Ideal:</strong> The training loss consistently drops over epochs.</p>
<p>There are various combinations and uses for loss curves. For more details, check out Google's <a target="_blank" href="https://developers.google.com/machine-learning/testing-debugging/metrics/interpretic">guide on interpreting loss curves.</a></p>
<h3 id="heading-how-to-deal-with-underfitting">How to deal with Underfitting</h3>
<ol>
<li><p><strong>Add more layers/units to your model</strong></p>
<p> If your model is underfitting, it might not be complex enough to capture the important patterns in the data. This means it's struggling to make accurate predictions. To improve its performance, you can increase the number of hidden layers or add more units to these layers, which helps the model learn more detailed and useful features from the data.</p>
</li>
<li><p><strong>Train for longer</strong></p>
<p> Sometimes a model just needs more time to learn representations of data. If you find in your smaller experiments your model isn't learning anything, perhaps leaving it train for a more epochs may result in better performance.</p>
</li>
<li><p><strong>Tweaking the learning rate</strong></p>
<p> This may help reduce underfitting by adjusting how quickly or slowly the model learns the data.</p>
<ul>
<li><p><strong>Increasing the Learning Rate</strong>: If the learning rate is too low, the model learns too slowly and misses patterns. Increasing the learning rate helps it learn faster, but if it's too high, the model might overshoot and become unstable.</p>
</li>
<li><p><strong>Decreasing the Learning Rate</strong>: If the learning rate is high, the model might make large updates that skip over optimal patterns, leading to poor learning. Reducing the learning rate allows the model to make smaller, more precise updates, potentially helping it better capture the data patterns.</p>
</li>
</ul>
</li>
<li><p><strong>Use transfer learning</strong></p>
<p> Transfer learning helps prevent overfitting and underfitting by leveraging patterns learned from a previously trained model and adapting them to your specific problem. Instead of starting from scratch, you use the knowledge from a model that has already learned useful features, which can improve learning efficiency and generalization for your own dataset.</p>
</li>
</ol>
<h3 id="heading-how-to-deal-with-overfitting">How to deal with Overfitting</h3>
<ol>
<li><p><strong>Use transfer learning</strong></p>
</li>
<li><p><strong>Get more data</strong></p>
<p> Having more data allows the model to identify a wider range of patterns and nuances, making it better at generalizing to new, unseen examples.</p>
</li>
<li><p><strong>Use data augmentation</strong></p>
<p> Data augmentation transforms the training data to introduce more variety and complexity, making it more challenging for the model to learn. By forcing the model to adapt to these variations, it can improve its ability to generalize to unseen data.</p>
</li>
<li><p><strong>Simplify your model</strong></p>
<p> If the current model is already overfitting the training data, it may be too complicated of a model. This means it's learning the patterns of the data too well and isn't able to generalize well to unseen data. One way to simplify a model is to reduce the number of layers it uses or to reduce the number of hidden units in each layer.</p>
</li>
<li><p><strong>Use early stopping</strong></p>
<p> Early stopping stops model training before it begins to overfit. As in, say the model's loss has stopped decreasing for the past 10 epochs (this number is arbitrary), you may want to stop the model training here and go with the model weights that had the lowest loss (10 epochs prior).</p>
</li>
</ol>
<h3 id="heading-the-balance-between-underfitting-and-overfitting">The balance between underfitting and overfitting</h3>
<p>The methods discussed above may not always work.</p>
<p>There is a thin line between overfitting and underfitting because too much of each can cause the other.</p>
<p>Transfer learning is a highly effective approach for addressing both overfitting and underfitting. By leveraging knowledge from a pre-trained model, it allows you to build on established patterns and features, helping your model adapt better to your specific problem and improving its performance even with limited data.</p>
]]></content:encoded></item><item><title><![CDATA[An Introduction to Express.js framework for Node.js Backend Programming .]]></title><description><![CDATA[The purpose of this article is to provide a guide for software developers looking to get started with Express.js to build application programming interfaces (APIs) with Create, Read, Update, Delete (CRUD) operations.
So let us build a CRUD API with E...]]></description><link>https://melvinlucas.hashnode.dev/an-introduction-to-expressjs-framework-for-nodejs-backend-programming</link><guid isPermaLink="true">https://melvinlucas.hashnode.dev/an-introduction-to-expressjs-framework-for-nodejs-backend-programming</guid><category><![CDATA[Express.js]]></category><category><![CDATA[backend]]></category><category><![CDATA[MVC architecture]]></category><category><![CDATA[MongoDB]]></category><dc:creator><![CDATA[Melvin Lucas]]></dc:creator><pubDate>Sun, 20 Aug 2023 07:02:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691737743814/677572ef-19e0-4064-90d2-218d6757b480.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The purpose of this article is to provide a guide for software developers looking to get started with Express.js to build application programming interfaces (APIs) with Create, Read, Update, Delete (CRUD) operations.</p>
<p>So let us build a CRUD API with Express.js and MongoDB.</p>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li><p>Knowledge of JavaScript and Node.js.</p>
</li>
<li><p>Basic knowledge of MongoDB ( I'll be using this as my database for the express.js project ).</p>
</li>
<li><p>Basic knowledge of MVC architecture ( I'll explain everything along the way ).</p>
</li>
</ul>
<h2 id="heading-getting-started-with-expressjs">Getting Started with Express.js</h2>
<p>Express.js is a fast and minimalistic web application framework for Node.js, a JavaScript runtime environment that is used to run server-side applications. Express is designed to simplify the process of building scalable web applications and APIs.</p>
<h3 id="heading-features-of-expressjs">Features of Express.js</h3>
<p>Express.js has some of the coolest features that make it easier for developers to handle various aspects of web development like routing, managing middleware, handling HTTP requests, API integration and more.</p>
<p>Let's discuss the above features before diving into the project.</p>
<ol>
<li><p>Routing. Express allows you to define endpoints for different URLs and HTTP methods ( GET, POST, PUT, DELETE). The routes determine how the application responds to client requests.</p>
</li>
<li><p>Middlewares. These are functions that help with handling the request-response cycle. Middleware functions are executed in sequence and help with enabling tasks throughout the application.</p>
</li>
<li><p>HTTP Request and Response Handling. When a client sends requests to your server, the server responds with data. When a request is sent, express routes that request to the appropriate route handler based on the URL and HTTP method. After the request goes through, a response is generated and sent to the client.</p>
</li>
</ol>
<p>API integration. Express simplifies the process of handling API endpoints and requests.</p>
<h2 id="heading-getting-into-express">Getting into Express.</h2>
<p>Assuming you have already installed node.js, make a new folder on your computer and open it using a text editor like VS Code.</p>
<p>You can also check the node version using the command: <code>node -v</code></p>
<p>The next step is to initialize an empty package.json to install and manage our dependencies: <code>npm init</code></p>
<p>That creates an empty package.json file at the root of your project which we will edit slightly.</p>
<p>Next, install express using the command <code>npm install express</code> and check that it is installed in the package.json under dependencies.</p>
<p>Next, create a <code>server.js</code> file at the root and inside the file let's create a server using express using the code block below.</p>
<p>Some of the things I like to do is put all my environment variables in a <code>.env</code> file and load them using <code>process.env.VariableName</code>, in my case I'm loading the PORT value. Any variable that you'd want to keep a secret goes into the env file. These variables include your MongoDB connection string, API keys etc.</p>
<p>You'll need to add dotenv library using <code>npm install dotenv</code> and create a <code>.env</code> file at the root.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
<span class="hljs-keyword">const</span> PORT = process.env.PORT || <span class="hljs-number">3500</span>;
app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`server listening on <span class="hljs-subst">${PORT}</span>`</span>);
});
</code></pre>
<p>To start the server.js, I will be installing a new dependency called <a target="_blank" href="https://www.npmjs.com/package/nodemon">nodemon</a> to automatically restart the application in case of any changes.</p>
<p>Run the command: <code>npm install nodemon --save-dev</code></p>
<p>We'll install it as a dev dependency as it is just needed for locally running the project and not functioning the project.</p>
<p>Next, let's edit the package.json to:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"notes-crud-api"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">" node server.js "</span>,
    <span class="hljs-attr">"dev"</span>: <span class="hljs-string">"nodemon server.js"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"dotenv"</span>: <span class="hljs-string">"^16.3.1"</span>,
    <span class="hljs-attr">"express"</span>: <span class="hljs-string">"^4.18.2"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"nodemon"</span>: <span class="hljs-string">"^3.0.1"</span>
  }
}
</code></pre>
<p>To run our server.js file just type <code>npm run dev</code> on the terminal and you will see the console message and the port number.</p>
<p>AND VOILA YOU HAVE CREATED A SERVER WITH EXPRESS!!.</p>
<p>Next, we'll set up the endpoints we will be hitting as:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>CRUD ACTIONS</td><td>HTTP Method</td><td>Endpoints</td></tr>
</thead>
<tbody>
<tr>
<td>Get all notes</td><td><mark>GET</mark></td><td>/api/notes</td></tr>
<tr>
<td>Get note</td><td><mark>GET</mark></td><td>/api/notes/:id</td></tr>
<tr>
<td>Create note</td><td><mark>POST</mark></td><td>/api/notes</td></tr>
<tr>
<td>Update note</td><td><mark>PUT</mark></td><td>/api/notes/:id</td></tr>
<tr>
<td>Delete note</td><td><mark>DELETE</mark></td><td>/api/notes/:id</td></tr>
</tbody>
</table>
</div><p>Onto exciting things, let's set up our HTTP methods. I will be using <a target="_blank" href="https://www.thunderclient.com/">ThunderClient</a> VS Code extension to test the endpoints locally but you can also use <a target="_blank" href="https://www.postman.com/">Postman</a>.</p>
<p>Here is the setup of the routes in the <code>server.js</code> file according to the wireframe above.</p>
<p>-Some key things to look out for: When getting a specific note we use the <code>id</code>. The same goes for updating and deleting.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
<span class="hljs-keyword">const</span> PORT = process.env.PORT;

<span class="hljs-comment">//Routes</span>
app.get(<span class="hljs-string">"/api/notes"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"here are all the notes"</span> });
});
app.get(<span class="hljs-string">"/api/notes/:id"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`get note for <span class="hljs-subst">${req.params.id}</span>`</span> });
});
app.post(<span class="hljs-string">"/api/notes"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"Create a note"</span> });
});
app.put(<span class="hljs-string">"/api/notes/:id"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`update note <span class="hljs-subst">${req.params.id}</span>`</span> });
});
app.delete(<span class="hljs-string">"/api/notes/:id"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`delete note <span class="hljs-subst">${req.params.id}</span>`</span> });
});
<span class="hljs-comment">//</span>
app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`server listening on <span class="hljs-subst">${PORT}</span>`</span>);
});
</code></pre>
<p>You can run your application and test out the routes using Thunderclient or Postman to make sure they return a status 200 along with the message.</p>
<p>To clean up the code above, we can extract the routes into their folder so as not to configure all routes in the server.js.</p>
<p>This means we are going to explore routing in express.js.</p>
<p>Routing in express is the process of directing incoming web requests to the right code in your application based on the URL and HTTP method.</p>
<p>We will make use of <code>express.Router()</code> which can be explained as: Imagine having a book that is grouped into folders that need to be tied together to make a story. Think of <code>express.Router()</code> as creating different folders(routes) that hold a set of related pages(routes and handlers). This way your code is organized and everything is clear.</p>
<p>With all that said, create a <code>route</code> folder on the root then add a <code>notesRoutes.js</code> file inside. We can now extract the routes that we created in the <code>server.js</code> into the <code>notesRoutes.js</code> as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> router = express.Router();

router.route(<span class="hljs-string">"/"</span>).get(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"here are all the notes"</span> });
});
router.route(<span class="hljs-string">"/:id"</span>).get(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`get note for <span class="hljs-subst">${req.params.id}</span>`</span> });
});
router.route(<span class="hljs-string">"/"</span>).post(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"Create a note"</span> });
});
router.route(<span class="hljs-string">"/:id"</span>).put(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`update note <span class="hljs-subst">${req.params.id}</span>`</span> });
});
router.route(<span class="hljs-string">"/:id"</span>).delete(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`delete note <span class="hljs-subst">${req.params.id}</span>`</span> });
});

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>From the above, you have extracted the routes into a routes folder and cleaned up the server.js. By exporting the module, we make it accessible in other parts of the file or application.</p>
<p>The server.js file will then look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
<span class="hljs-keyword">const</span> PORT = process.env.PORT;
<span class="hljs-comment">//middleware </span>
app.use(<span class="hljs-string">"/api/notes"</span>, <span class="hljs-built_in">require</span>(<span class="hljs-string">"./routes/notesRoutes"</span>));

app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`server listening on <span class="hljs-subst">${PORT}</span>`</span>);
});
</code></pre>
<p>We are using <code>app.use</code> in the server.js which is a helper to help manage the request and response cycle in our code. And that is what is called middleware. It handles all the HTTP methods defined in our <code>notesRoutes.js</code> file.</p>
<p>So in the above code block, we are telling the server.js to use the defined routes and providing the file path.</p>
<p>After separating your code, you can test the endpoints to make sure that everything is working as before.</p>
<p>The next step is the most interesting as we are separating the code using the Model, View and Controller (MVC) architecture. Since we are just building the backend, we'll implement the model and controller for the API.</p>
<p>Let's see how you can implement MVC for such a project.</p>
<h2 id="heading-mvc">MVC</h2>
<p>MVC is an architectural pattern used in software development and it separates the application into three interconnected parts: Model, View and Controller. Each component has a role and contributes to the overall structure and functionality of the application.</p>
<h3 id="heading-1-model">1. Model</h3>
<p>Responsible for maintaining the application's data. Models can be implemented through the use of MongoDB, MySQL, Oracle etc. The model is connected to the database. Also, this is where you define all your schemas eg using Mongoose in MongoDB. Adding and retrieving data is done in the model. The model responds to controller requests by moving back and forth retrieving data needed.</p>
<h3 id="heading-2-view">2. View</h3>
<p>Does data representation by rendering what the client sees on a browser. It generates the User Interface for the user. Views can contain templating engines such as EJS, PUG, and Handlebars. Views are created by the data which is collected by the model component. The data is taken through the controller.</p>
<h3 id="heading-3-controller">3. Controller</h3>
<p>The controller dictates how the application behaves and what data is sent to the model and view. It is the connection between the view and the model. It takes data from the model, processes it and then takes all the information to the view and explains how to represent it to the user.</p>
<p>In a web application, a Controller could manage URL routing, handle HTTP requests, and orchestrate interactions between the Model and the View. It ensures that user actions trigger the appropriate responses and updates.</p>
<p>Take a look at the flowchart summary:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691906270528/cc3344a3-7593-4be5-8a7a-597e25aa8a0c.png" alt class="image--center mx-auto" /></p>
<p>Advantages of MVC include:</p>
<ul>
<li><p>Separation of concerns.</p>
</li>
<li><p>Separates functionality into logical components.</p>
</li>
<li><p>The components are reusable throughout the application you just have to specify the path.</p>
</li>
<li><p>Easy to maintain.</p>
</li>
<li><p>Helps with testing individual components.</p>
</li>
</ul>
<p>Disadvantages</p>
<ul>
<li>Complexity is high.</li>
</ul>
<p>Now that we have an overview of the MVC design pattern, we will implement the same for our project.</p>
<p>Create a <code>controllers</code> folder at the root and add <code>notesController.js</code> file into it.</p>
<p>Inside the <code>notesController.js</code> we will be creating different controller functions that handle the HTTP requests.</p>
<p>The file will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//get all notes</span>
<span class="hljs-comment">//@route GET/api/notes</span>
<span class="hljs-keyword">const</span> getNotes = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"here are all the notes"</span> });
};

<span class="hljs-comment">//get a notes</span>
<span class="hljs-comment">//@route GET/api/notes/:id</span>
<span class="hljs-keyword">const</span> getNote = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`get note for <span class="hljs-subst">${req.params.id}</span>`</span> });
};
<span class="hljs-comment">//create or post a notes</span>
<span class="hljs-comment">//@route POST/api/notes</span>
<span class="hljs-keyword">const</span> createNote = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"Create a note"</span> });
};
<span class="hljs-comment">//update a note</span>
<span class="hljs-comment">//@route PUT/api/notes/:id</span>
<span class="hljs-keyword">const</span> updateNote = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`update note <span class="hljs-subst">${req.params.id}</span>`</span> });
};

<span class="hljs-comment">//delete a note</span>
<span class="hljs-comment">//@route DELETE/api/notes/:id</span>
<span class="hljs-keyword">const</span> deleteNote = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">`delete note <span class="hljs-subst">${req.params.id}</span>`</span> });
};

<span class="hljs-built_in">module</span>.exports = { getNotes, getNote, createNote, updateNote, deleteNote };
</code></pre>
<p>The <mark>getNotes</mark> controller function is responsible for handling a <mark>getnotes</mark> action. When triggered it sends a response with a status 200 (OK) and a JSON message <mark>"here are all the notes"</mark></p>
<p>The same goes for all the other HTTP methods.</p>
<p>Do not forget to export all your controller functions so they can be available for use in other parts of the applications.</p>
<p>Looking back to our <code>routes</code> folder and into the <code>notesRoutes.js</code> file, here is how we maintain the flow. Since we have separated our HTTP methods into the controller, we need to make use of the functions in the <code>notesRoutes.js</code> as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> router = express.Router();
<span class="hljs-keyword">const</span> notesController = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controllers/notesController"</span>);

router.route(<span class="hljs-string">"/"</span>).get(notesController.getNotes);
router.route(<span class="hljs-string">"/:id"</span>).get(notesController.getNote);
router.route(<span class="hljs-string">"/"</span>).post(notesController.createNote);
router.route(<span class="hljs-string">"/:id"</span>).put(notesController.updateNote);
router.route(<span class="hljs-string">"/:id"</span>).delete(notesController.deleteNote);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>In the above, we have attached the route handlers to the controller functions.</p>
<p>Inside the <code>.get()</code> method, the <code>notesController.getNotes</code> function is attached as the route handler. This means that when the defined route is accessed via a GET request, the <code>getNotes</code> function from the <code>notesController</code> module will be invoked to handle the request.</p>
<p>The same applies to the rest of the HTTP methods.</p>
<p>You can test your endpoints in Thunderclient to make sure you haven't broken anything.</p>
<p>Also, you can clean up the <code>notesRoutes.js</code> further as we have some common routes just to save on some lines.</p>
<p>The next step is to handle parsing data to the request body when creating a new note.</p>
<p>You realize that if you console.log the <code>req.body</code> in the <mark>createNote</mark> function in the controller and try to post data using thunderclient you get undefined on the console as shown below using an image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692072175705/82b1548a-55a9-4674-bfae-9b6f6811eb37.png" alt class="image--center mx-auto" /></p>
<p>We will make use of a middleware to parse incoming JSON data from requests and populate the <code>req.body</code> with the parsed data.</p>
<p>The middleware we will be using is : <code>app.use(express.json())</code> and you can add it in <code>server.js</code> just above the route handler middleware. You can try to pass data and check out the console for the title and content.</p>
<p>We also need to handle for when one passes an empty request body ie no title and content. You do this by adding a condition to check for the title and content of the note if there's no content it throws an error.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> createNote = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { title, content } = req.body;
    <span class="hljs-keyword">if</span> (!title || !content) {
      res.status(<span class="hljs-number">400</span>);
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"all fields are required!"</span>);
    }
    <span class="hljs-built_in">console</span>.log(req.body);
  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"Create a note"</span> });
};
</code></pre>
<p>Now that we are done setting up API endpoints, next is to add Create, Read, Update, Delete (CRUD) operations to the API using MongoDB.</p>
<h3 id="heading-mongodb">MongoDB</h3>
<p>MongoDB is a NoSQL database. That means instead of storing data in tables and rows like in relational databases, it stores data as a collection of documents.</p>
<p>For instance, we are collecting data about people(name, age, email), each person's information would be a document and all the documents make up a collection.</p>
<p>This provides a flexible and scalable way to store data.</p>
<h3 id="heading-moongose">Moongose</h3>
<p>Mongoose is an Object Data Modelling library that provides a high-level abstraction layer on top of MongoDB. It allows developers to specify their data models utilizing schemas.</p>
<p>A schema is a blueprint that defines the structure of a collection in a MongoDB database. It provides all the fields a document in a collection should have along with the data types and any validation requirements.</p>
<p>Here is a step to step guide on how to get started with MongoDB by <a target="_blank" href="https://www.youtube.com/watch?v=pWbMrx5rVBE">Traversy Media</a> and some more useful information on mongoose <a target="_blank" href="https://www.mongodb.com/developer/languages/javascript/getting-started-with-mongodb-and-mongoose/">HERE</a>.</p>
<p>After we can then create a database give it a name in my case I'll call my Database <mark>notes-backend </mark> and a collection name of <mark>notes</mark>.</p>
<p>Back to our project, install the Mongoose library: <code>npm install mongoose</code></p>
<p>Next, go back to the MongoDB atlas and grab your connection string and add it to the <code>env</code> file as <mark>DB_CONNECTION_STRING = string.</mark></p>
<p>Now to connect our database, create a <code>config</code> folder then add a <code>dbConnection.js</code> file then add the code below.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);

connectDB = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> connect = <span class="hljs-keyword">await</span> mongoose.connect(
      process.env.DB_CONNECTION_STRING
    );
    <span class="hljs-built_in">console</span>.log(
      <span class="hljs-string">"Database connected :"</span>,
      connect.connection.host,
      connect.connection.name
    );
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error);
    process.exit(<span class="hljs-number">1</span>);
  }
};
<span class="hljs-built_in">module</span>.exports = connectDB;
</code></pre>
<p>I have defined an asynchronous function <code>connectDB</code> that uses <code>mongoose.connect()</code> method with the mongoDB connection string obtained from our environment variable to connect to our database.</p>
<p>We then import the <code>connectDB</code> function into the <code>server.js</code> adding the exact file path and then invoking it. You should see the connection message on the console when you start your server.</p>
<p>Next, we create a schema for the notes.</p>
<p>According to the MVC design pattern the model holds our schema.</p>
<p>Create a new folder called <code>model</code> at the root then add <code>notesSchema.js</code> file.</p>
<p>The simplest way to design a schema is to consider the following:</p>
<ol>
<li><p>Get a clear understanding of your application's data requirements by this you'll know what to store.</p>
</li>
<li><p>Identify the fields needed for the application. In our case, we could just make use of title and content fields.</p>
</li>
<li><p>Data types and validation. Choose appropriate data types for each field (eg string, number, date). In our case, both will be strings. Define validation rules for the fields for data consistency and integrity (eg required, unique).</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);

<span class="hljs-keyword">const</span> notesSchema = mongoose.Schema(
  {
    <span class="hljs-attr">title</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"please add title"</span>],
    },
    <span class="hljs-attr">content</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"please add your notes"</span>],
    },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
  }
);
<span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">"notes"</span>, notesSchema);
</code></pre>
<p>The schema above specifies two required fields: "title" and "content," which hold the note's title and content. With the option <code>timestamps: true</code>, it automatically tracks the creation and update times of the document.</p>
<p>Now that we have established a MongoDB connection and created a schema we can then add crud operations to the APIs and check for the data in our database.</p>
<p>In the <code>notesController.js</code>, make use of the model to interact with the database.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Note = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/notesModel"</span>);

<span class="hljs-comment">//get all notes</span>
<span class="hljs-comment">//@route GET/api/notes</span>

<span class="hljs-keyword">const</span> getNotes = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> notes = <span class="hljs-keyword">await</span> Note.find();
    res.status(<span class="hljs-number">200</span>).json(notes);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"an error occurred"</span> });
  }
};

<span class="hljs-comment">//get a notes</span>
<span class="hljs-comment">//@route GET/api/notes/:id</span>
<span class="hljs-keyword">const</span> getNote = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> note = <span class="hljs-keyword">await</span> Note.findById(req.params.id);
    <span class="hljs-keyword">if</span> (!note) {
      res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"note not found"</span> });
    }
    res.status(<span class="hljs-number">200</span>).json(note);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"an error occurred"</span> });
  }
};
<span class="hljs-comment">//create or post a notes</span>
<span class="hljs-comment">//@route POST/api/notes</span>

<span class="hljs-keyword">const</span> createNote = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { title, content } = req.body;
    <span class="hljs-keyword">if</span> (!title || !content) {
      res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"all fields are required"</span> });
    }
    <span class="hljs-keyword">const</span> note = <span class="hljs-keyword">await</span> Note.create({ title, content });
    res.status(<span class="hljs-number">200</span>).json(note);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"an error occurred"</span> });
  }
};
<span class="hljs-comment">//update a note</span>
<span class="hljs-comment">//@route PUT/api/notes/:id</span>
<span class="hljs-keyword">const</span> updateNote = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> note = <span class="hljs-keyword">await</span> Note.findByIdAndUpdate(req.params.id, req.body, {
      <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span>,
    });
    <span class="hljs-keyword">if</span> (!note) {
      res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"note not found"</span> });
    }
    res.status(<span class="hljs-number">200</span>).json(note);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"an error occurred"</span> });
  }
};

<span class="hljs-comment">//delete a note</span>
<span class="hljs-comment">//@route DELETE/api/notes/:id</span>
<span class="hljs-keyword">const</span> deleteNote = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> note = <span class="hljs-keyword">await</span> Note.findByIdAndDelete(req.params.id);
    <span class="hljs-keyword">if</span> (!note) {
      res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"note not found"</span> });
    }
    res.status(<span class="hljs-number">200</span>).json(note);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"an error occurred"</span> });
  }
};

<span class="hljs-built_in">module</span>.exports = { getNotes, getNote, createNote, updateNote, deleteNote };
</code></pre>
<p><strong>CREATE</strong></p>
<p>In the above code block, we are checking for the presence of both title and content fields then proceeding to use the Mongoose <code>create</code> method to add a new note document in the MongoDB collection using the Note model.</p>
<p><strong>READ</strong></p>
<p>Makes use of the Mongoose <code>find</code> method to asynchronously retrieve all notes from the MongoDB collection using the Note model. To find a specific note, we use <code>findById</code> method based on the <mark>id</mark> parameter from the request.</p>
<p><strong>UPDATE</strong></p>
<p>Makes use of the Mongoose <code>findByIdAndUpdate</code> method to find an note by its <mark>id</mark> and update it using the provided request body. The <code>{ new: true }</code> option returns the updated note.</p>
<p><strong>DELETE</strong></p>
<p>Makes use of <code>findByIdAndDelete</code> Mongoose method to find a note by its <mark>id</mark> and delete it from the collection.</p>
<p>Add some notes to the database using Thunderclient and check for the notes in the database. Also, perform crud operations on the APIs and test all endpoints.</p>
<p>Here's the <a target="_blank" href="https://github.com/LucasMelvin15/notes-CRUD-API">link</a> to the GitHub repository for the backend code.</p>
<p>Feel free to add user authentication.</p>
]]></content:encoded></item><item><title><![CDATA[MVC Architecture]]></title><description><![CDATA[MVC is known as an architectural pattern that divides your software into smaller logical parts. MVC embodies 3 parts: Model, Views, Controller.

Model:
Responsible for maintaining data. Models can be implemented through use of MongoDB, MySQL, Oracle ...]]></description><link>https://melvinlucas.hashnode.dev/mvc-architecture</link><guid isPermaLink="true">https://melvinlucas.hashnode.dev/mvc-architecture</guid><dc:creator><![CDATA[Melvin Lucas]]></dc:creator><pubDate>Wed, 24 Aug 2022 06:58:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1661324114822/8B-CMaMhh.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>MVC is known as an architectural pattern that divides your software into smaller logical parts. MVC embodies 3 parts: Model, Views, Controller.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661324229253/drfRuiygC.png" alt="mvc f.png" /></p>
<p><strong>Model:</strong>
Responsible for maintaining data. Models can be implemented through use of MongoDB, MySQL, Oracle etc. The model is connected to the database. Also this is where you define all your schemas eg using Mongoose in MongoDB. Adding and retrieving data is done in the model. The model responds to controller requests by moving back and forth retrieving data needed. NB: The model never communicates with the view directly.</p>
<p><strong>View:</strong>
Does data representation by rendering what the client sees on a browser. It generates the User Interface for the user. Views can contain templating engines such as EJS, PUG, Handlebars.
Views are created by the data which is collected by the model component. The data is taken through the controller.</p>
<p><strong>Controllers:</strong>
Use a programming language eg JavaScript to dictate how the application behaves and what data is sent to the model and views. It is the connection between the views and model. It takes data from the model, processes it and then takes all the information to the view and explains how to represent to the user.</p>
<p><strong>Advantages of MVC</strong></p>
<ul>
<li>Separation of concerns</li>
<li>Separates functionality into logical components</li>
<li>The components are reusable through out the application you just have to specify the path</li>
<li>Easy to maintain </li>
<li>Helps with testing individual components</li>
</ul>
<p><strong>Disadvantages of MVC</strong></p>
<ul>
<li>Complexity is high</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Javascript Data Types]]></title><description><![CDATA[Data types are data items defined by the value it can take and the operations that can be performed on it. This means that a variable can hold value of a different type.
 Javascript primitive data types include;
 1.number
 2.string 
 3.boolean 
 4.nu...]]></description><link>https://melvinlucas.hashnode.dev/javascript-data-types</link><guid isPermaLink="true">https://melvinlucas.hashnode.dev/javascript-data-types</guid><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Melvin Lucas]]></dc:creator><pubDate>Fri, 06 May 2022 20:27:20 GMT</pubDate><content:encoded><![CDATA[<p>Data types are data items defined by the value it can take and the operations that can be performed on it. This means that a variable can hold value of a different type.
 Javascript primitive data types include;</p>
<p> 1.number
 2.string 
 3.boolean 
 4.null
 5.undefined<br /> 6.Bigint
 7.Symbol</p>
<p>And now to explain each type using examples</p>
<p><em>**</em>1.number</p>
<pre><code><span class="hljs-keyword">let</span> data = <span class="hljs-number">120</span>; <span class="hljs-comment">//declare a variable and initialize it's value with an integer</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span>(data));<span class="hljs-comment">// number</span>
</code></pre><p>Javascript uses  the <code>number</code>  type to represent both integers and floating-point values.
By floating-point I mean values that have decimal places (23.55)</p>
<p>  <strong>NaN</strong>
I'm sure you've seen this value in your console and it simply stands for Not a Number. It is a special numeric value that indicates an invalid number eg</p>
<pre><code> console.log(<span class="hljs-string">'i'</span> <span class="hljs-operator">/</span><span class="hljs-number">5</span>); <span class="hljs-comment">//  NaN</span>
</code></pre><p><strong>2.String</strong></p>
<p>To simply explain , a string is a sequence of one or more characters bounded by a string literal() that begins and ends with either a single quote or a double quote.</p>
<pre><code><span class="hljs-keyword">let</span> greeting = <span class="hljs-string">"Hello"</span> <span class="hljs-comment">//double quote</span>
<span class="hljs-keyword">let</span> message  = <span class="hljs-string">' how are you holding up ?'</span> <span class="hljs-comment">// single quote</span>
</code></pre><p>If you want to use a single quote in string after using the single quote then you have to escape it using a backlash.</p>
<pre><code>let message = <span class="hljs-string">'  I\m doing great'</span> // use \ <span class="hljs-keyword">to</span> <span class="hljs-keyword">escape</span> a single <span class="hljs-keyword">quote</span>
</code></pre><p><strong>3.boolean</strong></p>
<p>The <code>boolean</code>  type has two literal values either <code>true</code>  or <code>false</code> in lowercase.
Javascript allows other data types to be converted to boolean data types using <code>boolean()</code> function.
eg</p>
<pre><code>console.log(<span class="hljs-type">Boolean</span>(<span class="hljs-string">'Hello'</span>)) // <span class="hljs-keyword">true</span>
console.log(<span class="hljs-type">Boolean</span>(<span class="hljs-string">''</span>)) // <span class="hljs-keyword">false</span>
</code></pre><p><strong>4.null &amp; 5.undefined</strong></p>
<p>Javascript defines <code>null</code>  as equal to <code>undefined</code> .
Whenever a variable is declared but not initialized then the value is undefined .</p>
<pre><code>let day;
console.log(day) <span class="hljs-comment">// undefined</span>

console.log(null<span class="hljs-operator">=</span><span class="hljs-operator">=</span>undefined) <span class="hljs-comment">//true</span>
</code></pre><p> <strong>5 &amp; 6</strong></p>
<p>These are new forms of ES6  primitive data types and I'll update in simple terms once I understand better.</p>
<p>Enjoy the read folks and give your feedback too.</p>
]]></content:encoded></item></channel></rss>