<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Md Tanvir Hossain</title>
    <description>The latest articles on DEV Community by Md Tanvir Hossain (@csetanvir).</description>
    <link>https://dev.to/csetanvir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1043614%2F866a26e7-7fa9-4317-8bd8-59985ef7becf.png</url>
      <title>DEV Community: Md Tanvir Hossain</title>
      <link>https://dev.to/csetanvir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/csetanvir"/>
    <language>en</language>
    <item>
      <title>Build a full-stack application using Node.js, React and Atlas</title>
      <dc:creator>Md Tanvir Hossain</dc:creator>
      <pubDate>Tue, 21 Mar 2023 12:03:07 +0000</pubDate>
      <link>https://dev.to/csetanvir/build-a-full-stack-application-using-nodejs-react-and-atlas-288i</link>
      <guid>https://dev.to/csetanvir/build-a-full-stack-application-using-nodejs-react-and-atlas-288i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We will build a full-stack application using Node.js, React and &lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://nodejs.org/en"&gt;Node.js&lt;/a&gt;&lt;/strong&gt; is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser. It is designed to build scalable network applications and is often used for building server-side applications. Node.js provides an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://react.dev/"&gt;React&lt;/a&gt;&lt;/strong&gt; is a JavaScript library for building user interfaces. It allows developers to create reusable UI components and manage the state of those components. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;&lt;/strong&gt; is an open-source database schema management tool.  This tool allows you to inspect and modify your database, change schemas, and migrate your data. With the Atlas, , designing and creating new schemas for your database is straightforward, without the complexities of SQL syntax. &lt;/p&gt;

&lt;p&gt;By the end of the article, you will have a full-stack base that can be extended easily. Additionally, you will be introduced to &lt;strong&gt;&lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;&lt;/strong&gt;, which allows for the inspection, modification, schema-changing and migration of databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before going further, you need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://atlasgo.io/getting-started"&gt;Atlas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;MySQL database&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Npm&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;VS-Code (You can use any IDE or editor)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are also expected to have basic knowledge of these technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project structure:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project/
       api/
          config/
             dbConfig.js
          controllers/
             TodoController.js
          Models/
             index.js
             todoModel.js
          Routes/
             todoRoutes.js
          schema/
             schema.hcl (encoding must be UTF-8)
       .env
       index.js
       package.json

       front/
          public/
             index.html
          src/
             App.js
             index.css
             NewTodo.js
             Todo.js
             TodoList.js
       package.json
       postcss.config.js
       tailwind.config.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first step will be to create the project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir api
mkdir front

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Database inspect, design and migration using &lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;:
&lt;/h3&gt;

&lt;p&gt;We’ll design our database schema and migrate it into our database using &lt;a href="https://atlasgo.io/"&gt;atlas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For macOS + Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -sSf https://atlasgo.sh | sh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For windows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Download atlas from the latest release, rename it to atlas.exe, and move it to
"C:\Windows\System32" and access "atlas" from the PowerShell anywhere.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -d --name atlas-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=todo_atlas mysql


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a new container with the name “atlas-mysql” and sets the root user’s password to “pass“. It also creates a new database called “todo_atlas“.&lt;/p&gt;

&lt;p&gt;Connect to docker terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it atlas-mysq bash

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter this command to docker terminal to access mysql:-u flag mean the user, ie ”root” is the user and -p flag mean the password, ie. “pass” is the password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql -uroot -ppass

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new user and add privilege:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER 'todo_atlas_user'@'%' IDENTIFIED BY 'todo_atlas_password';
GRANT ALL ON todo_atlas.* TO 'todo_atlas_user'@'%'; 
FLUSH PRIVILEGES;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new user with the username “todo_atlas_use” and grant all privilege on the database name “todo_atlas”.&lt;/p&gt;

&lt;p&gt;Now create a schema folder inside &lt;code&gt;/api&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd api
mkdir schema
cd schema

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type the following to inspect your database through the atlas command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atlas schema inspect -u "mysql://todo_atlas_user:todo_atlas_password@localhost:3306/todo_atlas" &amp;gt; schema.hcl

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you open &lt;code&gt;/api/schema/schema.hcl&lt;/code&gt; with editor, you’ll find the schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schema "todo_atlas" {
  charset = "utf8mb4"
  collate = "utf8mb4_0900_ai_ci"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s design our database for our application (make sure schema.hcl has UTF-8 encoding):&lt;/p&gt;

&lt;p&gt;We will create one table name “todos” which will have four columns: "id", "title", "description" and "completed". &lt;br&gt;
To define a table we’ll use "table" keyword.&lt;br&gt;
To define a column we’ll use "column" keyword.&lt;br&gt;&lt;br&gt;
To define primary index we’ll use "primary_key" keyword.&lt;br&gt;
To define index we’ll use "index" keyword.&lt;/p&gt;

&lt;p&gt;We’ll define our schema using DDL(Data definition Language). You can learn more about DDL at &lt;a href="https://atlasgo.io/atlas-schema/sql-resources"&gt;Atlas-DDL&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schema "todo_atlas" {
  charset = "utf8mb4"
  collate = "utf8mb4_0900_ai_ci"
}

table "todos" {
  schema = schema.todo_atlas
  column "id" {
    null           = false
    type           = bigint
    unsigned       = true
    auto_increment = true
  }
  column "title" {
    null = false
    type = varchar(41)
  }
  column "description" {
    null = true
    type = text
  }
  column "completed" {
    null    = false
    type    = bool
    default = 0
  }
  primary_key {
    columns = [column.id]
  }
  index "todos_UN" {
    unique  = true
    columns = [column.title]
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s Time to migrate our schema into our database using “declarative schema migration” by following this simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atlas schema apply  -u "mysql://todo_atlas_user:todo_atlas_password@localhost:3306/todo_atlas" --to file://schema.hcl

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our schema is successfully migrated and we are ready for creating our todo-app.&lt;br&gt;
There is another type of migration which is versioned schema migration. To know more visit &lt;a href="https://atlasgo.io/versioned/diff"&gt;versioned workflow&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  API Setup
&lt;/h3&gt;

&lt;p&gt;Now that the database is all set up and all the dependencies have been installed, it’s time to create our application backend.&lt;/p&gt;

&lt;p&gt;Get back to our &lt;code&gt;/api&lt;/code&gt; folder from &lt;code&gt;/api/schema&lt;/code&gt; by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ..

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start a new project in  &lt;code&gt;/api&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to install these dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express cors dotenv nodemon

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Database Connector
&lt;/h3&gt;

&lt;p&gt;We first need a connection to the database so that we can use in our application.&lt;br&gt;
First, let's install the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install sequelize

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a &lt;code&gt;.env&lt;/code&gt; with required variables in &lt;code&gt;/api&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#database
HOST ='localhost' 
USER ='todo_atlas_user' 
PASSWORD ='todo_atlas_password' 
DATABASE ='todo_atlas' 

#application backend
PORT = 5000

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;dbConfig.js&lt;/code&gt; in &lt;code&gt;/api/configs/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dotenv = require('dotenv');
let result = dotenv.config(); 

module.exports = {
    HOST:  process.env.HOST,
    USER: process.env.USER,
    PASSWORD: process.env.PASSWORD,
    DB: process.env.DATABASE,
    dialect: 'mysql',

    pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Model
&lt;/h3&gt;

&lt;p&gt;We’ll create the model to interact with our database. We’ll create our model todo in the &lt;code&gt;todoModel.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = (sequelize, DataTypes) =&amp;gt; {

    const todo = sequelize.define("todos", {

        title: {
            type: DataTypes.STRING
        },

        description: {
            type: DataTypes.TEXT
        },
        completed: {
            type: DataTypes.BOOLEAN
        }

    }, {
        timestamps: false // disable timestamps
    })

    return todo
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll access our model from &lt;code&gt;index.js&lt;/code&gt;, Create &lt;code&gt;index.js&lt;/code&gt; in &lt;code&gt;/api/models/&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dbConfig = require('../configs/dbConfig.js');
const {Sequelize, DataTypes} = require('sequelize');

const sequelize = new Sequelize(
    dbConfig.DB,
    dbConfig.USER,
    dbConfig.PASSWORD, {
        host: dbConfig.HOST,
        dialect: dbConfig.dialect,
        operatorsAliases: false,

        pool: {
            max: dbConfig.pool.max,
            min: dbConfig.pool.min,
            acquire: dbConfig.pool.acquire,
            idle: dbConfig.pool.idle

        }
    }
)

sequelize.authenticate()
.then(() =&amp;gt; {
    console.log('connected...')
})
.catch(err =&amp;gt; {
    console.log('Error :'+ err)
})

const db = {}
db.Sequelize = Sequelize
db.sequelize = sequelize
db.todo = require('./todoModel.js')(sequelize, DataTypes)
db.sequelize.sync({ force: false })
.then(() =&amp;gt; {
    console.log('yes re-sync done!')
}).catch(err =&amp;gt; {
    console.log('Error :'+ err)
})

module.exports = db

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Controller
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;todoController.js&lt;/code&gt; in &lt;code&gt;/api/controllers&lt;/code&gt;, we’ll create a controller function for every route-request:&lt;br&gt;
First, we’ll import and initialise our model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const db = require('../models')
const todos = db.todo

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll create a controller function &lt;code&gt;createTodo&lt;/code&gt;, for creating new todo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 1. create todo
const createTodo = async (req, res) =&amp;gt; {
    let info = {
                title: req.body.title,
                description: req.body.description ? req.body.description : "No description yet" ,
                published: 0
            }
    try {
      // Check if the title already exists in the database
      let todo = await todos.findOne({ where :{title : info.title }});
      if (todo!=null) {
        // Title already exists, return a 409 (Conflict) error
        res.status(409).json({ message: 'Title already exists' });
        return;
      }

      // Title does not exist, insert the new todo into the database
      if(req.body.title.length&amp;lt;41){
        let todo = await todos.create(info);
        res.status(201).json(todo);
      }
      else{
        res.status(409).json({ message: 'Title is too long' });
      }
    } catch (err) {
      console.error(err);
      res.status(500).json({ message: 'Internal Server Error'+err });
    }
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll create another function &lt;code&gt;getAllTodos&lt;/code&gt;, for getting all our todo list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 2. get all todos
const getAllTodos =async (req, res) =&amp;gt; {
    try {
      let todo = await todos.findAll()
      console.log(todo)
      res.status(200).json(todo)
    } catch (err) {
      console.error(err);
      res.status(500).json({ message: 'Internal Server Error' })
    }
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll create &lt;code&gt;updateTodo&lt;/code&gt;, to update the todo status when we need to change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // 3. update todo by id
  const updateTodo = async (req, res) =&amp;gt; {
    try{
    let id = req.params.id
    let todo = await todos.update(req.body, { where: { id: id }})
    res.status(200).send(todo)
    }catch(err){
        console.error(err);
        res.status(500).json({ message: 'Internal Server Error' })
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll create another function &lt;code&gt;deleteTodo&lt;/code&gt;, for deleting a todo by its Id:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 4. delete todo by id
const deleteTodo = async (req, res) =&amp;gt; {
try{
    let id = req.params.id
    await todos.destroy({ where: { id: id }} )
    res.status(200).send('Todo is deleted !')
 }catch(err){
        console.error(err);
        res.status(500).json({ message: 'Internal Server Error'+err })
    }   
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll create last controller function &lt;code&gt;deleteAll&lt;/code&gt;, for deleting all todo in the list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 5. delete all todos
const deleteAll = async (req, res) =&amp;gt; {
    try{
        await todos.destroy({truncate : true} )
        res.status(200).send('All todos are deleted !')
     }catch(err){
            console.error(err);
            res.status(500).json({ message: 'Internal Server Error'+err })
        }      
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, We’ll export our controller functions so that it is accessible from the router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    createTodo,
    getAllTodos,
    updateTodo,
    deleteTodo,
    deleteAll
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Router
&lt;/h3&gt;

&lt;p&gt;We'll define all routes regarding our API.&lt;br&gt;
A router defines a set of routes, each associated with a specific HTTP method (e.g., GET, POST, PUT, DELETE). When a request is made to a route, the router will match the URL to the appropriate route and execute the associated code in Controller.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;todoRoutes.js&lt;/code&gt; in &lt;code&gt;/api/routes&lt;/code&gt;, we’ll create a router for every route-request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// import controllers 
const todoController = require('../controllers/todoController')
// router instance
const router = require('express').Router()
// defining routes
 router.get('/todos', todoController.getAllTodos)
 router.post('/todos',todoController.createTodo)
 router.put('/todos/:id',todoController.updateTodo)
 router.delete('/todos/:id',todoController.deleteTodo)
 router.delete('/delete-all',todoController.deleteAll)

module.exports = router

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Api
&lt;/h3&gt;

&lt;p&gt;This is our API. This application manages all the requests and processes through the controller and middleware.&lt;br&gt;
Create &lt;code&gt;server.js&lt;/code&gt; in &lt;code&gt;/api&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const cors = require('cors')

// expess initializes
const app = express()

// middleware
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// router
const router = require('./routes/todoRoutes.js')
app.use('/api/v1', router)

//port
const PORT = process.env.PORT || 5000

//server
app.listen(PORT, () =&amp;gt; {
    console.log(`server is running on port ${PORT}`)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now configure &lt;code&gt;package.json&lt;/code&gt; for running our api:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"main": "server.js", 
"scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1",
    "dev": "nodemon server",
    "start": "node server"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run Api
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start 
or 
npm run dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference between two are, &lt;code&gt;npm start&lt;/code&gt; don’t support hot reloading but &lt;code&gt;npm run dev&lt;/code&gt; does.&lt;br&gt;
Our api should be running on port 5000.&lt;/p&gt;

&lt;p&gt;If you are confused about the dependencies, visit the &lt;a href="https://github.com/cseTanvir/todo-node-app-atlas-cli/tree/main/api"&gt;GitHub&lt;/a&gt; directory.&lt;/p&gt;
&lt;h2&gt;
  
  
  Frontend Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Initialize React
&lt;/h3&gt;

&lt;p&gt;Goto &lt;code&gt;/front&lt;/code&gt; and create React app by the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app ./ 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the  following in &lt;code&gt;/front/package.json&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "Todo-Frontend",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000",
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "autoprefixer": "^10.4.14",
    "axios": "^1.3.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      "&amp;gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "tailwindcss": "^3.2.7"
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to install all the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;tailwind.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}",],
  theme: {
    extend: {},
  },
  plugins: [],
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;postcss.config.js&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    plugins: [
      require('tailwindcss'),
      require('autoprefixer'),
    ]
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete all content in &lt;code&gt;/front/src&lt;/code&gt; and  Create &lt;code&gt;index.js&lt;/code&gt; in &lt;code&gt;/front/src/&lt;/code&gt; :&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;index.css&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;index.css&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(&amp;lt;App /&amp;gt;);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create components
&lt;/h3&gt;

&lt;p&gt;We’ve installed all the dependencies for React and also configured TailwindCSS. It’s time to make the components for the Frontend of the application.&lt;br&gt;
Create &lt;code&gt;NewTodo.js&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';
const NewTodo = ({ addTodo }) =&amp;gt; {
  const [title, setTitle] = useState('');
  const handleSubmit = e =&amp;gt; {
    e.preventDefault();
    addTodo({
      title: title,
      completed: false
    });
    setTitle('');
  };
  return (
    &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;input type="text" placeholder="Add a new Todo" value={title} onChange={e =&amp;gt; setTitle(e.target.value)} /&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Add&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};
export default NewTodo;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;Todo.js&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
const Todo = ({ todo, deleteTodo, toggleCompleted }) =&amp;gt; {
  return (
    &amp;lt;div className="todo"&amp;gt;
      &amp;lt;input
        type="checkbox"
        checked={todo.completed}
        onChange={() =&amp;gt; toggleCompleted(todo.id)}
      /&amp;gt;
      &amp;lt;span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}&amp;gt;{todo.title}&amp;lt;/span&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; deleteTodo(todo.id)}&amp;gt;Delete&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
export default Todo; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;TodoList.js&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import Todo from './Todo';
const TodoList = ({ todos, deleteTodo, toggleCompleted }) =&amp;gt; {
  return (
    &amp;lt;div className="todo-list"&amp;gt;
      {todos.map(todo =&amp;gt; (
        &amp;lt;Todo key={todo.id} todo={todo} deleteTodo={deleteTodo} toggleCompleted={toggleCompleted} /&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
};
export default TodoList;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Front-end
&lt;/h3&gt;

&lt;p&gt;We already made our components, now we’ll create the frotend of our Todo app.&lt;br&gt;
Create &lt;code&gt;App.js&lt;/code&gt; in &lt;code&gt;/front/src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';
import axios from 'axios';
const base = "api/v1";


function App() {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');
  const [error, setError] = useState('');

  useEffect(() =&amp;gt; {
    axios.get(base+'/todos')
      .then(response =&amp;gt; {
        setTodos(response.data);
      })
      .catch(error =&amp;gt; {
        console.log(error);
      });
  }, []);

  const handleInputChange = (event) =&amp;gt; {
    setNewTodo(event.target.value);
  };

  const handleAddTodo = () =&amp;gt; {
    if (newTodo.trim() === '') {
      return;
    }

    axios.post(base+'/todos', { title: newTodo })
      .then(response =&amp;gt; {
        setTodos([...todos, response.data]);
        setNewTodo('');
        setError('');
      })
      .catch(error =&amp;gt; {
        setError(error);
        console.log(error);
      });
  };

  const handleDeleteTodo = (id) =&amp;gt; {
    axios.delete(base+`/todos/${id}`)
      .then(response =&amp;gt; {
        setTodos(todos.filter(todo =&amp;gt; todo.id !== id));
      })
      .catch(error =&amp;gt; {
        console.log(error);
      });
  };

  const handleToggleTodo = (id) =&amp;gt; {
    const updatedTodos = todos.map(todo =&amp;gt; {
      if (todo.id === id) {
        todo.completed = !todo.completed;
      }
      return todo;
    });

    axios.put(base+`/todos/${id}`, { completed: updatedTodos.find(todo =&amp;gt; todo.id === id).completed })
      .then(response =&amp;gt; {
        setTodos(updatedTodos);
      })
      .catch(error =&amp;gt; {
        console.log(error);
      });
  };

  return (
    &amp;lt;div className='container mx-auto bg-mnblue'&amp;gt;
      &amp;lt;div className="flex flex-col items-center h-screen bg-grey-300"&amp;gt;
      &amp;lt;h1 className=' py-2 font-bold text-white'&amp;gt;Todo App&amp;lt;/h1&amp;gt;
      &amp;lt;div className='flex-col py-2 mb-2' &amp;gt;
      &amp;lt;input aria-label="Todo input"  className="mr-2 shadow appearance-none border rounded w-80 py-2 px-3 text-black leading-tight focus:outline-none focus:shadow-outline "type="text" value={newTodo} onChange={handleInputChange} placeholder="Add task." /&amp;gt;
      &amp;lt;button className="shadow bg-mint px-3 hover:bg-mint-light focus:shadow-outline focus:outline-none text- font-bold py-1 px-1 rounded" onClick={handleAddTodo} &amp;gt;Add Todo&amp;lt;/button&amp;gt;
      {error? (&amp;lt;div className='mt-2 p-1 text-center bg-gray-300' style={{ color: 'red' }}&amp;gt;{error.response.data.message}&amp;lt;/div&amp;gt;) : (&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;)}
      &amp;lt;/div&amp;gt;
      &amp;lt;div style={{borderTop:"solid 2px black"}}&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;ul className="flex  flex-col  w-full " style={{ listStyle: 'none' , maxWidth: '500px'}} &amp;gt;
        {todos.map(todo =&amp;gt; (
          &amp;lt;li className='bg-saffron flex p-1 m-1 rounded' key={todo.id}  &amp;gt;
            &amp;lt;input  aria-label="Todo status toggle" className="px-2 "  type="checkbox" checked={todo.completed} onChange={() =&amp;gt; handleToggleTodo(todo.id)}   /&amp;gt;
            &amp;lt;span className="mx-2 text-center flex-1 " style={{ textDecoration: todo.completed ? 'line-through' : 'none',  color: todo.completed ? '#FB4D3D' : 'black' }}&amp;gt;{todo.title}&amp;lt;/span&amp;gt;
            &amp;lt;button className="float-end bg-tomato hover:bg-white hover:text-tomato focus:shadow-outline focus:outline-none text-white font-bold mx-auto mr-1 px-1 rounded" onClick={() =&amp;gt; handleDeleteTodo(todo.id)} &amp;gt;Delete&amp;lt;/button&amp;gt;
          &amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run Front-end
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial we learned how to create a full-stack application with Node.js, React and &lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;. Thanks for reading so far and I hope you enjoyed it!&lt;/p&gt;

</description>
      <category>atlas</category>
      <category>node</category>
      <category>react</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
