I need help with moving my finished todo to a "finished list" instead of the del-tag using html to overline the finished todo. Anyone have a clue on how I should do this?
import React, {useContext, useEffect, useState} from 'react'
import UserContext from '../UserContext'
import axios from 'axios'
export default function Home() {
const userInfo = useContext(UserContext)
const [inputValue, setInputValue] = useState("")
const [todos, setTodos] = useState([])
useEffect(() => {
axios.get("http://localhost:3001/todos", {withCredentials: true})
.then(response => {
setTodos(response.data)
})
}, [])
if(!userInfo.username) {
return "Login to list todos"
}
function addTodo() {
axios.put("http://localhost:3001/todos", {text: inputValue}, {withCredentials: true})
.then(response => {
setTodos([...todos, response.data])
setInputValue("")
})
}
function updateTodo(todo) {
const data = {id: todo._id, isDone: !todo.isDone}
axios.post('http://localhost:3001/todos', data, {withCredentials: true})
.then(() => {
const newTodos = todos.map(t => {
if (t._id === todo._id) {
t.isDone = !t.isDone;
}
return t
})
setTodos([...newTodos])
})
}
return <div>
<form onSubmit={e => addTodo(e)}>
<input placeholder={'What do you want to do?'}
value={inputValue}
onChange={e => setInputValue(e.target.value)}/>
</form>
<ul>
{todos.map(todo => (
<li>
<input type={"checkbox"}
checked={todo.isDone}
onClick={() => updateTodo(todo)}
/>
{todo.isDone ? <del>{todo.text}</del> : todo.text}
<p>Created at: {todo.createdAt}</p>
</li>
))}
</ul>
</div>
}
I was thinking maybe I should add something like this:
<div>
<select>
<option value="completed">Completed</option>
<option value="uncompleted">Uncompleted</option>
</select>
But how can I change the onClick function so it moves to the completed list, and vice versa, how can I change it back from completed list to the uncompleted?
This is my Todo model in backend:
import mongoose from 'mongoose';
const todoSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
isDone: {
type: mongoose.SchemaTypes.Boolean,
required: true
},
user: {
type: mongoose.SchemaTypes.ObjectId
},
createdAt: {
type: Date,
default: Date.now
}
}, {timestamps: true});
const Todo = mongoose.model('Todo', todoSchema);
export default Todo;
CodePudding user response:
You can try following code, I hope it will help you
const [completedTodos, setCompletedTodos] = useState([]);
const [uncompletedTodos, setUncompletedTodos] = useState([]);
useEffect(() => {
if(todos.length){
let tempCompletedTodos = todos.filter(item => item.isDone)
let tempUncompletedTodos = todos.filter(item => !item.isDone)
setCompletedTodos(tempCompletedTodos);
setUncompletedTodos(tempUncompletedTodos);
}
}, [todos])
CodePudding user response:
You can filter in JSX too and without creating a new list. It would be:
<h1>To-do</h1>
<ul>
{todos.filter(i => !i.isDone).map(todo => (
<li>
<input type={"checkbox"}
checked={todo.isDone}
onClick={() => updateTodo(todo)}
/>
{todo.text}
<p>Created at: {todo.createdAt}</p>
</li>
))}
</ul>
<h1>Finished</h1>
<ul>
{todos.filter(i => i.isDone).map(todo => (
<li>
<input type={"checkbox"}
checked={todo.isDone}
onClick={() => updateTodo(todo)}
/>
{todo.text}
<p>Created at: {todo.createdAt}</p>
</li>
))}
</ul>
You can try here: https://codesandbox.io/s/dazzling-ives-coc85e?file=/src/App.js