Follow me on LinkedIn
Follow me on Github.com
skipping boaring section π
recommend for beginners;
1. Setting Up the Backend
mkdir mern-todo-app
cd mern-todo-app
npm init -y
1.2. Install Dependencies
`npm install express mongoose body-parser cors
`
1.3. Set Up the Server
Create an index.js file to set up the Express server and connect to MongoDB.
// index.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 5000;
mongoose.connect('mongodb://localhost:27017/todoapp', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB');
});
app.use(bodyParser.json());
app.use(cors());
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
1.4. Create Mongoose Models
Create a models directory and define the Todo model.
// models/Todo.js
const mongoose = require('mongoose');
const todoSchema = new mongoose.Schema({
text: { type: String, required: true },
completed: { type: Boolean, default: false },
createdAt: { type: Date, default: Date.now },
});
const Todo = mongoose.model('Todo', todoSchema);
module.exports = Todo;
1.5. Create Routes
Create a routes directory and define the routes for the CRUD operations
// routes/todoRoutes.js
const express = require('express');
const Todo = require('../models/Todo');
const router = express.Router();
// Create a new todo
router.post('/', async (req, res) => {
try {
const todo = new Todo({
text: req.body.text,
});
await todo.save();
res.status(201).json(todo);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// Get all todos
router.get('/', async (req, res) => {
try {
const todos = await Todo.find();
res.status(200).json(todos);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// Update a todo
router.put('/:id', async (req, res) => {
try {
const todo = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.status(200).json(todo);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// Delete a todo
router.delete('/:id', async (req, res) => {
try {
await Todo.findByIdAndDelete(req.params.id);
res.status(200).json({ message: 'Todo deleted successfully' });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
module.exports = router;
Integrate the routes into the index.js file.
// index.js
const todoRoutes = require('./routes/todoRoutes');
app.use('/api/todos', todoRoutes);
2. Setting Up the Frontend
2.1. Initialize the React Project
Create a new React project using Create React App.
npx create-react-app client
cd client
2.2. Install Dependencies
Install Axios for making HTTP requests.
npm install axios
2.3. Create Components
Create a components directory and add the following components: TodoList, TodoItem, and TodoForm.
TodoList Component
// src/components/TodoList.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import TodoItem from './TodoItem';
import TodoForm from './TodoForm';
const TodoList = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
fetchTodos();
}, []);
const fetchTodos = async () => {
const response = await axios.get('http://localhost:5000/api/todos');
setTodos(response.data);
};
const addTodo = async (text) => {
const response = await axios.post('http://localhost:5000/api/todos', { text });
setTodos([...todos, response.data]);
};
const updateTodo = async (id, updatedTodo) => {
const response = await axios.put(`http://localhost:5000/api/todos/${id}`, updatedTodo);
setTodos(todos.map(todo => (todo._id === id ? response.data : todo)));
};
const deleteTodo = async (id) => {
await axios.delete(`http://localhost:5000/api/todos/${id}`);
setTodos(todos.filter(todo => todo._id !== id));
};
return (
<div>
<h1>Todo List</h1>
<TodoForm addTodo={addTodo} />
{todos.map(todo => (
<TodoItem
key={todo._id}
todo={todo}
updateTodo={updateTodo}
deleteTodo={deleteTodo}
/>
))}
</div>
);
};
export default TodoList;
TodoItem Component
// src/components/TodoItem.js
import React from 'react';
const TodoItem = ({ todo, updateTodo, deleteTodo }) => {
const toggleComplete = () => {
updateTodo(todo._id, { ...todo, completed: !todo.completed });
};
return (
<div>
<input
type="checkbox"
checked={todo.completed}
onChange={toggleComplete}
/>
<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</span>
<button onClick={() => deleteTodo(todo._id)}>Delete</button>
</div>
);
};
export default TodoItem;
TodoFormComponent
// src/components/TodoForm.js
import React, { useState } from 'react';
const TodoForm = ({ addTodo }) => {
const [text, setText] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
addTodo(text);
setText('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Add a new todo"
/>
<button type="submit">Add</button>
</form>
);
};
export default TodoForm;
2.4. Integrate Components in App
Update the App.js file to include the TodoList component.
// src/App.js
import React from 'react';
import TodoList from './components/TodoList';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
2.5. Run the Application
Start the backend server and the React frontend.
`# In the root directory
node index.js
In the client directory
npm start
`
Top comments (22)
Liquid syntax error: 'raw' tag was never closed
I'll try to do more better next time
Ya, I'll next time bro
any solutions?
use optional channing or null check
{todos?.map(todo => (
key={todo._id}
todo={todo}
updateTodo={updateTodo}
deleteTodo={deleteTodo}
/>
))}
I think you where wrongly type your code!
here the correct :
{todos?.map(todo => (
key={todo._id}
todo={todo}
updateTodo={updateTodo}
deleteTodo={deleteTodo}
/>
))}
eg: let x = [1,2,3,4];
you can use optional chaining, right?
{x?.map((val,index)=><div>{val}</div>)}
again a good option bro
Hi,which resource do you recommend to learn mern stack ?
Always recommend using each documentations,
Identify, learn & understands other's codes from git for more.
And bro, always go with yourself taught that will create magic
I thought create-react-app was no longer used?
It's there but ur choice to use bro, I think you know vite, vite is best to use.
it simple, thanks
your welcome bro
Nice to Learn
Wow, it's really concise:)
nice explanation
Great job. Thanks
Really helpful for me as a beginner in Backend development
Ya bro
Amazing π but I believe you should go for vite instead of create-react-app