Edit user information in React - reactjs

I am using axios to get and post user information, but I am somewhat lost on how to handle editing a user's information. I have created a working put endpoint, but I am lost on how to change to editable text in React
User component:
const handleEdit = (user) => {
axios
.put(`/api/User/${user.id}`)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
return(
<div className="container white">
<h3 className="center">
User List
<Button className="btn-createUser" color="info">
<Link to='/signup'>Add New User</Link>
</Button>
</h3>
<form className="inline-form">
{users.list.map(user => (
<div className="section" key={user.id}>
<div className="divider"></div>
<h5 className="user-userName">{user.username}</h5>
<h5 className="user-userEmail">{user.email}</h5>
<Button className="btn-delete" color="info" onClick={() => handleDelete(user)}>Delete</Button>
<Button className="btn-edit" color="info" onClick={() => handleEdit(user)}>Edit</Button>
</div>
))}
</form>
</div>
);

const [users] = useState([]); //declare users array at top then use setUsers to update
handleChange = event => {
const index = users.findIndex(user => user.userName = event.target.value);
users[index].userName = event.target.value;
setUsers(users);
}

you need to set userName and userEmail in state first. the onChange method will capture new updates.
<input
type="text"
name="username"
value={this.state.username}
onChange={this.handleChange}
/>
handleChange = event => {
this.setState({ username: event.target.value });
};

Related

strapi and react form not adding data to the admin

previous issue
building a rating app using strapi and react throws errors is solved.
But, the records are not getting added to the admin.
can anyone help on this?
This is the code to add and read reviews from strapi admin,
function App() {
const stars = Array(5).fill(0);
const [currentValue, setCurrentValue] = React.useState(0);
const [hoverValue, setHoverValue] = React.useState(undefined);
const handleClick = (value) => {
setCurrentValue(value);
};
const handleMouseOver = (value) => {
setHoverValue(value);
};
const [review, setReview] = useState({});
const [reviews, setReviews] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await api.readReviews();
//console.log(result.data);
setReviews(result.data.data);
};
fetchData();
}, []);
const createReview = async () => {
try {
//console.log(review);
const data = await api.createReview(review);
setReview([...reviews, data]);
} catch (error) {
//console.log(error);
}
};
let [reviewCount, setreviewCount] = useState([]);
const setCountFxn = (no) => {
setReview(no);
};
return (
<>
<form>
<div style={styles.container}>
<h2>RATE OUR SERVICE</h2>
<div style={styles.stars}>
{stars.map((_, index) => {
return (
<FaStar
key={index}
size={24}
style={{
marginRight: 10,
cursor: 'pointer',
}}
color={(hoverValue || currentValue) > index ? colors.orange : colors.grey}
onClick={() => {
setReview({ ...review, Rating: index + 1 });
}}
onMouseOver={() => handleMouseOver(index + 1)}
/>
);
})}
</div>
<div>
<input
type='text'
placeholder='input your name'
required
style={styles.input}
value={review.Name}
onChange={(e) => setReview({ ...review, Name: e.target.value })}
/>
</div>
<textarea
placeholder="what's your feedback"
required
style={styles.textarea}
value={review.review}
onChange={(e) => setReview({ ...review, review: e.target.value })}
/>
<button type='submit' style={styles.button} className='btn btn-primary' onClick={createReview}>
submit
</button>
</div>
</form>
<section id='reviews'>
<div className='reviews-heading'>
<span>REVIEWS FROM CUSTOMERS</span>
</div>
<div className='container'>
<div className='row'>
{reviews.map((review, i) => (
<div key={review.id} className='col-md-6'>
<div className='reviews-box'>
<div className='box-top'>
<div className='profile'>
<div className='name-user'>
<strong>{review.attributes.Title}</strong>
</div>
</div>
<div style={styles.stars}>
{Array.from({ length: review.attributes.Rating }).map((i) => (
<FaStar key={i} size={18} color={colors.orange} />
))}
</div>
</div>
<div className='client-comment'>{review.attributes.Body}</div>
</div>
</div>
))}
</div>
</div>
</section>
</>
);
}
export default App;
The form gets submitted and reloads after submit, but the record does not get added to strapi admin. I've set the roles of the data to public.
thanks
Nabi
You need a very specific structure to create a new entry with strapi. I assume your payload looks like this:
{
name: 'xyz',
rating: 5
}
Correct would be:
{
data: {
name: 'xyz',
rating: 5
}
}
Strapi Docs - Creating an entry
Ive figured it out!
The values of the form were named wrong. "Name" should be "Title" and "review" should be "Body". It now adds the data to the strapi admin.

How to instantly post data using Axios after inserting it

I need to refresh my page in order to see any added data I put into my cluster. I have been trying to add a .then() statement after I take in data through the front end in order to post it immediately after the 'Add to List' button is clicked. I've done the same with update and delete (it instantaneously changes on client), but I just need a bit of help with how to do the same with inserting/creating! Thanks!
Here is my some of my front-end code (const addToList and HTML later in the code)...
const addToList = () => {
Axios.post("http://localhost:3001/insert",
{
foodName: foodName,
amount: amount }
)};
<div className="inputarea">
<label id='foodname'>Food Name:</label>
<input type="text" onChange={(event) => {setFoodName(event.target.value)}}/>
<label id='amountneeded'>Amount Needed:</label>
<input type="number" onChange={(event) => {setAmount(event.target.value)}}/>
<button id='addButton' onClick={addToList}><span>Add To List</span></button>
<h1>Food List:</h1>
{foodList.map((val, key) => {
return (
<div className='dataContainer'>
<div className='foodList' key={key}>
<h1 id='groceryList'>
{val.foodName}: {val.amount}
</h1>
<div className='buttonContainer'>
<input type="number" id='numberInput' placeholder = "Update number of items here!" onChange={(event) => {setNewFoodNumber(event.target.value)}}></input>
<button id='change' onClick={() => updateFoodNumber(val._id)}><span>Update!</span></button>
<button id='delete' onClick={() => deleteFood(val._id)}><span>Delete!</span></button>
</div>
</div>
</div>
)
})}
</div>
and my back-end (app.post)!
app.post('/insert', async (req, res) => {
const foodName = req.body.foodName
const amount = req.body.amount
const food = new foodModel({foodName: foodName, amount: amount});
try {
await food.save();
res.send("inserted data!");
} catch(err) {
console.log(err)
}});

Can someone help me with the deleting data in firebase firestore using react ? it is a Todo list and i don't know what i am missing in the code

Component where my delete button is. i am trying to get to the collection in firestore an delete the post using its id. but nothing shows up. i don't know what i am missing. even if i think the syntax makes sense
function TodoList({id, title, icon}) {
const deleteTodo = ()=>{
db.collection('Todo').doc(id).delete()
}
return (
<div className="todoList" >
<h4 className="title">{title}</h4>
<div className="icons">
{icon && <DeleteIcon className="icon" onClick={deleteTodo} />}
{icon ? <CheckIcon className="icon1"/> : ""}
</div>
</div>
)
}
piece of code where i save the data in database. using db.collection firebase:
function TodoInput() {
const [todos, setTodos] = useState("");
const [saved, setSaved] = useState([]);
useEffect(() => {
db.collection('Todo').orderBy('timestamp', 'desc').onSnapshot(snapshot => {
setSaved(snapshot.docs.map(doc =>({
id: doc.id,
data: doc.data(),
})))
})
}, [])
const handleSubmit = (e)=>{
e.preventDefault();
if(!todos){
}else{
db.collection('Todo').add({
title: todos,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
})
}
setTodos('');}
return (
<div className="todoInput" >
<form >
<input required type="text" placeholder="What to do ?" value={todos}
onChange={(e)=>setTodos(e.target.value)} />
<button type="submit" onClick={handleSubmit} >ADD TODO</button>
</form>
<div className="todoListWrapper">
<div className="todoListItem" >
{saved.map(({id, data:{title}})=>(
<TodoList className="todoList1" key={id} title={title} icon />
))}
</div>
</div>
</div>
)
}

How do I send data to my backend by clicking on save the page with REACT

How is it possible to send these data (Taste, Trust, content of question all questions (which are in Tabs.jsx), everything except the description see the picture please) to my backend by clicking on 'Save the page'.In first part before putting any url inside, I really want to see the data in the console log for now I have nothing printed out except this message :
SyntheticBaseEvent {_reactName: "onClick", _targetInst: null, type: "click", nativeEvent: PointerEvent, target: HTMLButtonElement…}
I have 2 versions but I don't know the difference, what is better to use, I just saw these 2 ways in this forum.
export default function MenuItemDisplay() {
const [data, setData] = useState({
taste: "",
trust: ""
});
function onSubmit(e) {
e.preventDefault();
axios
.post("", {
trust: data.trust,
taste: data.taste
})
.then((res) => {
console.log(res.data);
});
}
function handleSubmit(e) {
const newData = { ...data };
newData[e.target.id] = e.target.value;
setData(newData);
console.log(e);
}
const onError = () => {
console.log("Error");
};
function Checkbox({ value }) {
const [checked, setChecked] = useState(true);
return (
<label>
<input
type="checkbox"
defaultChecked={checked}
onChange={() => setChecked(!checked)}
/>
{value}
</label>
);
}
return (
<>
<h1> {item.name} </h1>
<div>
<div className="TextStyle">
{"Taste "}
<Dropdown ... /> .
</div>
...
<Checkbox value={!!item.trust} />
</div>
...
<button
type="submit"
onClick= {handleSubmit}
> Save the content
</button>
</>
);
}
OR the same code with fetch :
export default function MenuItemDisplay() {
const [trust, setTrust] = useState("item.trust");
const [taste, setTaste] = useState("item.taste");
const [message, setMessage] = useState("");
let handle = async (e) => {
e.preventDefault();
try {
let res = await fetch("", {
method: "POST",
body: JSON.stringify({
trust: trust,
taste: taste
})
});
let resJson = await res.json();
if (res.status === 200) {
setTaste("");
setTrust("");
message("Success");
} else {
setMessage("Some error occured");
}
} catch (err) {
console.log(err);
}
};
return (
<>
<form onSubmit={hadle}>
<h1> {item.name} </h1>
<div>
<div className="TextStyle">
{"Taste "}
<Dropdown
style={styles.select}
options={TASTE}
defaultValue={TASTE.find((t) => t.label === item.taste)}
styleSelect={colourStyles}
isMulti={true}
/>
</div>
<div className="TextStyle">
{"Trust "}
<Checkbox value={!!item.trust} />
</div>
<div className="TextStyle"> Description : {item.description} </div>
<Tabs data={item.questions} />
</div>
<button>Save</button>
</form>
</>
);
}
Plus I have another form inside my MenuItemDisplay component that is Tabs.jsx. I really don't don't how can I deal with these 2 forms and how to 'trace' these data...
Here is my code
You can go with the following approaches.
Using a form element
You need to send the form data to the backend using AJAX calls. The most conventional way to do so is to use a JSX form element.
export default function MenuItemDisplay() {
...
return (
<form onSubmit={handleSubmit}>
<h1> {item.name} </h1>
<div>
<div className="TextStyle">
{"Taste "}
<Dropdown
style={styles.select}
options={TASTE}
defaultValue={TASTE.find((t) => t.label === item.taste)}
styleSelect={colourStyles}
isMulti={true}
/>
</div>
<div className="TextStyle">
{"Trust "}
<Checkbox value={!!item.trust} />
</div>
<div className="TextStyle"> Description : {item.description} </div>
<Tabs data={item.questions} />
</div>
<button type="submit"> Save the page</button>
</form>
);
}
Using a handleSubmit callback to the save button
Another way to do it using the button to send the request to the backend when clicked.
export default function MenuItemDisplay() {
...
return (
<>
<h1> {item.name} </h1>
<div>
<div className="TextStyle">
{"Taste "}
<Dropdown
style={styles.select}
options={TASTE}
defaultValue={TASTE.find((t) => t.label === item.taste)}
styleSelect={colourStyles}
isMulti={true}
/>
</div>
<div className="TextStyle">
{"Trust "}
<Checkbox value={!!item.trust} />
</div>
<div className="TextStyle"> Description : {item.description} </div>
<Tabs data={item.questions} />
</div>
<button onClick={handleSubmit}> Save the page</button>
</>
);
}
All you need to do is define the handleSubmit callback. If you use the form element, you'd need to prevent the default form submission behavior.
async function handleSubmit(e) {
e.preventDefault(); // if you use the form tag
// validate the data here
// use fetch or axios or any other 3rd party library to send data to the back end
// receive response from backend
// do something with the response
}

REACT JS FIREBASE FIRESTORE- how can i update my field in a document?

here is my manageexam.jsx file
this is where the update happen when i click the manage button on the table. i want to update a specific document id (3BelYq7lMxRNrWKknCRK- this is a sample of my document id but ofcourse there will be a lot of document id when i will add more inside the collection.) but i want to update the fields without manually adding the document Id that i want to update.
const ManageExam = () => {
const [description,setDesc]=useState("")
const [title,setTitle]=useState("")
function handleUpdate(e){
e.preventDefault();
const examcollref = doc(db,'Exams' "3BelYq7lMxRNrWKknCRK")
updateDoc(examcollref,{
title:title,
description:description
} ).then(response => {
alert("updated")
}).catch(error =>{
console.log(error.message)
})
}
return (
<div className="manageExam">
<Sidebar/>
<div className="manageExamContainer">
<div className="examInfo">
<h1>Manage Exam</h1>
</div>
<div className="left">
<div className="leftForm">
<div className="leftTitle">
Exam information
</div>
<br />
<div className="leftTitle">
</div>
<form onSubmit={handleUpdate}>
<label >Exam Title</label>
<input
type="text"
placeholder={title.doc}
value={title}
onChange={e => setTitle(e.target.value)}/>
<label htmlFor="">Description</label>
<textarea
id="desc"
cols="30"
rows="7"
value={description}
onChange={e =>setDesc(e.target.value)}
></textarea>
<button type="submit">Update</button>
</form>
</div>
</div>
<div className="right">
<div className="rightForm">
<div className="rightTitle">
Add Questions
<Link to= {`add_question`}style={{textDecoration:"none"}} className="link" >
Add new
</Link>
</div>
<div className="rightContainer">
{/* <p>1. What is the Meaning of db?</p> */}
{/* <div>
<input type="radio" name="option1" value="database" checked/>
<label htmlFor="">database</label>
</div>
<div>
<input type="radio" name="option2" value="data" disabled/>
<label htmlFor="">data</label>
</div>
<div>
<input type="radio" name="option3" value="databytes" disabled/>
<label htmlFor="">databytes</label>
</div>
<div>
<input type="radio" name="option4" value="databoard" disabled/>
<label htmlFor="">databoard</label>
</div>
<br />
<button>update</button>
<button>delete</button> */}
</div>
</div>
</div>
</div>
</div>
)
}
export default ManageExam
export const Examtable = ({id}) => {
const [list,setExamlist] = useState([])
// function to call the list from the firestore
useEffect (()=>{
const unsub = onSnapshot(
collection(db, "Exams"), //"exams -> pangalan ng database/("collection") ko"
(snapShot) => {
let list = [];
snapShot.docs.forEach((doc) => {
list.push({ id: doc.id, ...doc.data() });
});
setExamlist(list);
console.log(list.id);
},
(error) => {
console.log(error);
}
);
return () => {
unsub();
};
},[]);
const handleDelete = async (id) => {
alert("Do you want to delete?")
//window.confirm("Are you sure you want to delete?");
try {
await deleteDoc(doc(db, "Exams", id));
setExamlist(list.filter((item) => item.id !== id));
console.log(id)
} catch (err) {
console.log(err);
}
};
const actionColumn = [{field: "action", headerName: "Action", width: 200, renderCell:(params)=>{
return(
<div className="cellAction">
<div className="manageButton"> {/*/exam/manage_exam*/}
<Link to={`/exam/manage_exam/${params.row.id}`} style={{textDecoration:"none"}} className="link" >
Manage
</Link>
</div>
<div className="deleteButton" onClick={() => handleDelete(params.row.id)}>Delete</div>
</div>
)
}}];
return (
<div className="examtable" >
<div className="examtableTitle">
Exam
<Link to="/exam/new_exam/" style={{textDecoration:"none"}} className="link">
Add new
</Link>
</div>
<DataGrid
className="datagrid"
rows={list} //eto mga list nung nasa firebase
columns={examColumns.concat(actionColumn)}
pageSize={9}
rowsPerPageOptions={[9]}
checkboxSelection
/>
</div>
)
}
export default Examtable
here is the examtable.jsx where all the document in the collection will be displayed.
when i click the manage button, the url will display like this (localhost:3000/exam/manageexam/3BelYq7lMxRNrWKknCRK,, its because i click on this document but i cant update it at all because the console always said the id was undefined. i hope you understand what im saying
Because your pass id with Link in Examtable file.I think u must use useParams from react-router-dom in ur ManageExam.
First you need add id in your route path file, like this.
path: '/exam/manageexam/:id'
And then, in ur ManageExam.
import {useParams} from 'react-router-dom'
const ManageExam = () => {
const {id} = useParams()
const [description,setDesc]=useState("")
const [title,setTitle]=useState("")
function handleUpdate(e){
e.preventDefault();
const examcollref = doc(db,'Exams', id)
updateDoc(examcollref,{
title:title,
description:description
} ).then(response => {
alert("updated")
}).catch(error =>{
console.log(error.message)
})

Resources