Reputation: 205
I am building a goal setter app in MERN using JWT. I've done the creating and deleting goals, however, I am getting a token error with the update tasks function. It's pretty much the same as deleting goals, getting the goals._id. Here's what my code looks like:
Update and delete goal slice (note that delete one works)
// Update goal
export const updateGoal = createAsyncThunk(
"goals/update",
async (id, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token;
return await goalService.updateGoal(id, token);
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
return thunkAPI.rejectWithValue(message);
}
}
);
// Delete goal
export const deleteGoal = createAsyncThunk(
"goals/delete",
async (id, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token;
return await goalService.deleteGoal(id, token);
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
return thunkAPI.rejectWithValue(message);
}
}
);
goalService.js
const updateGoal = async (goalId, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
};
const response = await axios.put(API_URL + goalId, config);
return response.data;
};
the front-end
function GoalItem({ goal }) {
const dispatch = useDispatch();
const [editing, isEditing] = useState(false);
const onSubmit = (e) => {
e.preventDefault();
dispatch(updateGoal(goal._id))
};
return (
<>
<div className="goal">
<div>{new Date(goal.createdAt).toLocaleString("en-US")}</div>
<h2>{goal.text}</h2>
<button
onClick={() => dispatch(deleteGoal(goal._id))}
className="close"
>
X
</button>
<button onClick={() => isEditing(true)} className="btn-sml">
Edit
</button>
{editing && (
<section className="form">
<form onSubmit={onSubmit}>
<div className="form-group">
<input
type="text"
name="text"
id="text"
/>
</div>
<div className="form-group">
<button className="btn btn-block" type="submit">Update goal</button>
</div>
</form>
</section>
)}
</div>
</>
);
}
// @desc Update goal
// @route PUT /api/goals/:id
// @access Private
const updateGoal = asyncHandler(async (req, res) => {
const goal = await Goal.findById(req.params.id)
if(!goal) {
res.status(400)
throw new Error('Goal not found')
}
// Check for user
if(!req.user) {
res.status(401)
throw new Error('User not found')
}
// Make sure the logged in user matches goal user
if(goal.user.toString() !== req.user.id){
res.status(401)
throw new Error('User not authorized')
}
const updatedGoal = await Goal.findByIdAndUpdate(req.params.id, req.body, {new:true,})
res.status(200).json(updatedGoal);
});
Upvotes: 0
Views: 76
Reputation: 1512
In your repo. You have passed config as second argument which is for data in goalService.updateGoal.
const response = await axios.put(API_URL + goalId, config);
Change this to
const response = await axios.put(API_URL + goalId, null ,config);
Also you are using ReactDOM.render which is not supported in react 18
Use createRoot
import ReactDOM from 'react-dom/client';
// other imports
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render([...])
Upvotes: 1