i am getting an error "400 bad request" i can't find out what is my error
below i share my frontend and backend code..
i am also share my image error link that i came
https://ibb.co/swQPgYG
################### backend ######################
todoschema.js
this is a todoschema
var mongoose = require('mongoose');
var todoSchema = new mongoose.Schema({
name: {
type: String,
required: true,
maxlength:32,
trim:true
}
},{timestamps:true}
)
module.exports = mongoose.model('Todo',todoSchema)
auth.js/router
var express = require('express');
var router = express.Router();
const {addTodo} = require('../controller/auth');
router.post('/addtodo',addTodo);
module.exports = router;
auth.js/controller
const Todo = require('../model/todo');
exports.addTodo = (req,res) =>{
const todo = new Todo(req.body)
todo.save((err,todo) => {
if(err || !todo){
return res.status(400).json({
err : 'NOT able to store data in database'
})
}
res.json(todo);
})
}
################## frontEnd ###########################
API == http://localhost:8000/api/
here i fetch request from my backend
index.js
import {API} from '../backend'
import axios from 'axios'
export const getdata = (todo) => {
return (dispatch) => {
axios.post(`${API}addtodo`)
.then(res => {
console.log(res)
dispatch({
type : 'FETCH_TODO',
payload : todo
})
})
.catch(err =>{
console.log(err);
})
}
}
This is the todoForm where i add my todo
todoform.js
import React,{useState, useEffect} from 'react'
import '../App.css'
import {
FormGroup,
Input,
Button,
Form,
InputGroup,
InputGroupAddon
} from 'reactstrap';
import {v4} from 'uuid';
import 'bootstrap/dist/css/bootstrap.min.css';
import {getdata } from '../Auth'
//redux
import {connect, useDispatch} from 'react-redux'
import {addTodo} from '../Action/todo';
const TodoForm = ({addTodo}) => {
const [title,setTitle] = useState('')
const dispatch = useDispatch();
useEffect(() => {
dispatch(getdata())
}, []);
return(
<Form>
<FormGroup>
<InputGroup>
<Input
type='text'
name='todo'
id='todo'
placeholder='Your next Todo'
value={title}
onChange={e => setTitle(e.target.value)}
/>
<InputGroupAddon addonType='prepend'>
<Button color='primary' onClick={()=>{
if(title === ''){
return alert('please add a todo')
}
const todo = {
title,
id:v4(),
}
addTodo(todo);
setTitle('');
}}>
ADD
</Button>
</InputGroupAddon>
</InputGroup>
</FormGroup>
</Form>
)
}
const mapStateToProps = state => ({
})
const mapDispatchToProps = dispatch =>({
addTodo : todo =>{
dispatch(addTodo(todo))
},
})
export default connect(mapStateToProps,mapDispatchToProps)(TodoForm)
getData(todo) - action creator function require argument
export const getdata = (todo) => {
return (dispatch) => {
axios.post(`${API}addtodo`)
.then(res => {
console.log(res)
dispatch({
type : 'FETCH_TODO',
payload : todo
})
})
.catch(err =>{
console.log(err);
})
}
}
and you call it without argument
const dispatch = useDispatch();
useEffect(() => {
dispatch(getdata())
}, []);
Related
I'm on a MERN stack to create a chat application.
And when I'm trying to display notifications when there is a new message in another chatroom or a new PM I'm having this issue :
Sidebar.js:99 Uncaught TypeError: Cannot read properties of undefined (reading 'Tech')
at Sidebar.js:99:1
at Array.map (<anonymous>)
Tech is a room in an array, server side.
And problem is on front side :
<ul className='chatroom'>
{rooms.map((room, idx) => (
<li
key={idx}
onClick={() => joinRoom(room)}
className={room === currentRoom ? 'actif' : ''}
>
{room}
{currentRoom !== room &&
<span className='notifs'>
{user.newMessages[room]}
</span>
}
</li>
))}
</ul>
on this part particulary :
{currentRoom !== room &&
<span className='notifs'>
{user.newMessages[room]}
</span>
I tried a lot of things, starting by testing if the state is here with a ternary or a conditional. But nothing more. And it works because the first part with {room} is working great, all rooms displays on a list.
I'm on it since three days, I'm losing all my hairs 🤣 so if you have any idea...
I'm putting parts of the code if it can help
Sidebar.js
import React, { useContext, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { AppContext } from '../../context/appContext';
import { Div } from './Sidebar.elements'
import { addNotifications, resetNotifications } from '../../features/userSlice'
import { FaCircle } from 'react-icons/fa'
function Sidebar() {
const user = useSelector((state) => state.user);
const dispatch = useDispatch();
const {
socket,
setMembers,
members,
setCurrentRoom,
setRooms,
privateMemberMsg,
rooms,
setPrivateMemberMsg,
currentRoom
} = useContext(AppContext)
function joinRoom(room, isPublic = true){
if(!user){
return alert("Veuillez vous identifier");
}
socket.emit("join-room", room);
setCurrentRoom(room);
if (isPublic){
setPrivateMemberMsg(null);
}
// dispatch for notifications
dispatch(resetNotifications(room));
}
socket.off("notifications").on("notifications", (room) => {
if(currentRoom !== room) dispatch(addNotifications(room));
console.log(room);
});
function getRooms(){
fetch("http://localhost:5001/rooms")
.then((res) => res.json())
.then((data) => setRooms(data));
}
useEffect(()=>{
if(user){
setCurrentRoom('General');
getRooms();
socket.emit('join-room', 'General');
socket.emit('new-user');
}
},[])
socket.off('new-user').on('new-user', (payload) => {
setMembers(payload);
})
function orderIds(id1, id2) {
if(id1 > id2) {
return id1 + "-" + id2;
} else {
return id2 + "-" + id1;
}
}
function handlePrivateMemberMsg(member){
setPrivateMemberMsg(member);
const roomId = orderIds(user._id, member._id);
joinRoom(roomId, false);
}
if(!user){
return <></>;
}
return (
<>
<Div>
<h2>Chatrooms disponibles</h2>
<ul className='chatroom'>
{rooms.map((room, idx) => (
<li
key={idx}
onClick={() => joinRoom(room)}
className={room === currentRoom ? 'actif' : ''}
>
{room}
{currentRoom !== room &&
<span className='notifs'>
{user.newMessages[room]}
</span>
}
</li>
))}
</ul>
<h2 className='chat'>Chaters</h2>
<ul className='membre'>
{members.map((member) => (
<li
key={member.id}
className={`
${privateMemberMsg?._id === member?._id ? 'actif' : ''}
${member._id === user._id ? 'disabling' : ''}
`}
onClick={() => handlePrivateMemberMsg(member)}
>
<div className="row">
<div className="col-2">
<img src={member.picture} className='member-pic'/>
{member.status == "En ligne" ? <FaCircle className='online'/> : <FaCircle className='offline'/>}
</div>
<div className="col-9">
{member.name}
{member._id == user?._id && " (Vous)"}
{member.status == "Hors Ligne" && <span className="offtxt">(Offline)</span> }
</div>
<div className="col-1">
<span className="notifs">
{/* {user.newMessages[orderIds(member._id, user._id)]} */}
</span>
</div>
</div>
</li>
))}
</ul>
</Div>
</>
)
}
export default Sidebar
appApi.js
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react'
// define a service user and base URL
const appApi = createApi({
reducerPath: 'appApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://localhost:5001'
}),
endpoints: (builder) => ({
// creating the user
signupUser: builder.mutation({
query: (user) => ({
url: '/users',
method: "POST",
body: user,
}),
}),
// login
loginUser: builder.mutation({
query: (user) => ({
url:'/users/login',
method: "POST",
body: user,
}),
}),
//logout
logoutUser: builder.mutation({
query: (payload) => ({
url: '/logout',
method: "DELETE",
body: payload,
}),
}),
}),
});
export const { useSignupUserMutation, useLoginUserMutation, useLogoutUserMutation } = appApi;
export default appApi;
appContext.js
import { io } from 'socket.io-client'
import React from 'react'
const SOCKET_URL = "http://localhost:5001";
export const socket = io(SOCKET_URL);
//app context
export const AppContext = React.createContext()
userSlice.js
import { createSlice } from "#reduxjs/toolkit";
import appApi from "../services/appApi";
export const userSlice = createSlice({
name: "user",
initialState: null,
reducers: {
addNotifications: (state, { payload }) => {
if (state.newMessages[payload]) {
state.newMessages[payload] = state.newMessages[payload] + 1;
} else {
state.newMessages[payload] = 1;
}
},
resetNotifications: (state, { payload }) => {
delete state.newMessages[payload];
},
},
extraReducers: (builder) => {
// save user after signup
builder.addMatcher(appApi.endpoints.signupUser.matchFulfilled, (state, { payload }) => payload);
// save user after login
builder.addMatcher(appApi.endpoints.loginUser.matchFulfilled, (state, { payload }) => payload);
// logout : destroy user session
builder.addMatcher(appApi.endpoints.logoutUser.matchFulfilled, () => null);
},
})
export const { addNotifications, resetNotifications } = userSlice.actions;
export default userSlice.reducer;
server.js on back side
const express = require('express');
const app = express();
const userRoutes = require('./routes/userRoutes');
const User = require('./models/User');
const Message = require('./models/Message');
const rooms = [
'General',
'Tech',
'Crypto',
'Gaming'
];
const cors = require('cors');
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(cors());
app.use('/users', userRoutes)
require('./connection')
const server = require('http').createServer(app);
const PORT = 5001;
const io = require('socket.io')(server, {
cors: {
origin: 'http://localhost:3000',
methods: ['GET', 'POST']
}
})
app.get('/rooms', (req, res)=> {
res.json(rooms)
})
async function getLastMessagesFromRoom(room){
let roomMessages = await Message.aggregate([
{$match: {to: room}},
{$group: {_id: '$date', messagesByDate: {$push: '$$ROOT'}}}
])
return roomMessages;
}
function sortRoomMessagesByDate(messages){
return messages.sort(function(a, b){
let date1 = a._id.split('/');
let date2 = b._id.split('/');
date1 = date1[2] + date1[0] + date1[1];
date2 = date2[2] + date2[0] + date2[1];
return date1 < date2 ? -1 : 1
})
}
// socket connection
io.on('connection', (socket)=> {
socket.on('new-user', async ()=>{
const members = await User.find();
io.emit('new-user', members);
})
socket.on('join-room', async(room)=> {
socket.join(room);
let roomMessages = await getLastMessagesFromRoom(room);
roomMessages = sortRoomMessagesByDate(roomMessages);
socket.emit('room-messages', roomMessages);
})
socket.on('message-room', async(room, content, sender, time, date) => {
const newMessage = await Message.create({content, from: sender, time, date, to: room});
let roomMessages = await getLastMessagesFromRoom(room);
roomMessages = sortRoomMessagesByDate(roomMessages);
// sending message to room
io.to(room).emit('room-messages', roomMessages);
// And send notification when sending new message
socket.broadcast.emit('notifications', room)
})
app.delete('/logout', async(req, res)=>{
try {
const {_id, newMessages} = req.body;
const user = await User.findById(_id);
user.status = "Hors Ligne";
user.newMessages = newMessages;
await user.save();
const members = await User.find();
socket.broadcast.emit('new-user', members);
res.status(200).send();
} catch (e) {
console.log(e);
res.status(400).send();
}
})
})
server.listen(PORT, () => {
console.log('listening to port ', PORT);
})
Edit
Adding the App.js that I forgot
App.js
import './App.css';
import {
BrowserRouter as Router,
Route,
Routes
} from 'react-router-dom'
import Home from './pages/Home';
import Login from './pages/Login';
import Signup from './pages/Signup';
import Chat from './pages/Chat';
import GlobalStyle from './GlobalStyles';
import { useSelector } from 'react-redux';
import { useState } from 'react';
import { AppContext, socket } from './context/appContext'
function App() {
const [rooms, setRooms] = useState([]);
const [currentRoom, setCurrentRoom] = useState([]);
const [members, setMembers] = useState([]);
const [messages, setMessages] = useState([]);
const [privateMemberMsg, setPrivateMemberMsg] = useState({});
const [newMessages, setNewMessages] = useState({});
const user = useSelector((state) => state.user);
return (
<AppContext.Provider value={{
socket,
currentRoom,
setCurrentRoom,
members,
setMembers,
messages,
setMessages,
privateMemberMsg,
setPrivateMemberMsg,
newMessages,
setNewMessages,
rooms,
setRooms
}} >
<Router>
<GlobalStyle/>
<Routes>
<Route path="/" element={<Home/>} />
{!user && (
<>
<Route path="/login" element={<Login/>} />
<Route path="/signup" element={<Signup/>} />
</>
)}
<Route path="/chat" element={<Chat/>} />
</Routes>
</Router>
</AppContext.Provider>
);
}
export default App;
I'm building a react app using redux for state management.
Inside the SearchField component I am using useReducer for handle the search field inputs (cityField and countryField).
When i submit the fetchData function runs and sends a request to an API.
the SearchField component code:
import React, { useReducer } from "react";
import { connect } from 'react-redux';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { reducer, INITIAL_STATE } from "../../redux/search-field/search-field.reducer";
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
fetchData(cityField, countryField);
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
const mapDispatchToProps = dispatch => ({
fetchData: (cityField, countryField) => dispatch(fetchData(cityField, countryField))
})
export default connect(null, mapDispatchToProps)(SearchField);
The problem is that when the OnFormSubmit function is called, the fetchData function does not send any request and there is no errors in the console. The searchField and countryField data are stored correctly (or at least if I show them in the console I get the actual values). The fetchData function was previously located in the App and worked correctly.
I thank in advance anyone who gives me an answer and tries to find the solution.
The fetchData code:
export const fetchData = (cityField, countryField) => {
return (dispatch) => {
dispatch(fetchCurrentDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${cityField},${countryField}&units=metric&appid=MY_API_KEY`)
.then(response => {
const currentData = response.data
dispatch(fetchCurrentDataSuccess(currentData));
const { lat, lon } = currentData.coord
dispatch(fetchDailyDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&units=metric&exclude=current,minutely,hourly,alerts&appid=MY_API_KEY`)
.then(response => {
const dailyData = response.data.daily
dispatch(fetchDailyDataSuccess(dailyData))
})
.catch(error => {
const errorMessage = error.message
dispatch(fetchCurrentDataFailure(errorMessage))
})
})
.catch(error => {
const errorMessage = error.message
alert('No results found')
dispatch(fetchCurrentDataFailure(errorMessage))
})
}
I resolved using useDispatch hook instead of mapdispatchToProps, so the new code is:
import React, { useReducer } from "react";
import { useDispatch } from 'react-redux';
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { reducer, INITIAL_STATE } from '../../redux/search-field/search-field.reducer';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const dispatchData = useDispatch();
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
dispatchData(fetchData(cityField, countryField));
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
export default SearchField;
I am building a react application and part of the application is a quiz section. At the end of the quiz there is a button which can save the user score in the quiz to the database.
This is my express route
// #route Put api/profile/saveScore/:id
// #desc Save users quiz score to profile
// #access Private
router.put('/saveScore/:topic_id', checkObjectId('topic_id'), auth, async (req, {params: {topic_id } }, res) => {
const score = req.body.score
const topic = topic_id
const newUserTopic = {
score,
topic,
}
try {
const profile = await Profile.findOne({ user: req.user.id });
profile.topics.unshift(newUserTopic);
await profile.save();
res.json(profile)
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
})
The express route works no bother in postman so thinking the issue must be more on the react side.
This is my action route
// Save Quiz Score to users profile
export const saveScore = (topicId, payload) => async (dispatch) => {
try {
const res = await api.put(`/profile/saveScore/${topicId}`, payload);
dispatch({
type: GET_PROFILE,
payload: res.data
});
dispatch(setAlert('Topic Saved', 'success'));
} catch (err) {
const errors = err.response.data.errors;
if(errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')))
}
dispatch({
type: PROFILE_ERROR,
payload: { msg: err.response.statusText, status: err.response.status }
});
}
};
This is my component
import React, { useEffect, useState, Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import QuizItem from './QuizItem';
import { getTopicById } from '../../actions/topic';
import { saveScore} from '../../actions/profile';
import { SaveScoreForm } from './SaveScoreForm';
const Quiz = ({ getTopicById, saveScore, topic: { topic, loading }, match }) => {
useEffect(() => {
getTopicById(match.params.id);
}, [getTopicById, match.params.id])
const [currentIndex, setCurrentIndex] = useState(0);
const [score, setScore] = useState(0);
const [showAnswers, setShowAnswers] = useState(false)
const [formData, setFormData] = useState({ score })
const handleAnswer = (answer) => {
if(!showAnswers) {
if(answer === topic[currentIndex].correct_answer) {
setScore(score + 1);
}
}
setShowAnswers(true);
};
const handleNextQuestion = () => {
setShowAnswers(false);
setCurrentIndex(currentIndex + 1);
}
console.log(currentIndex)
const onChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value })
}
const onSubmit = (e) => {
e.preventDefault();
const payload = new FormData();
payload.append('score', formData.score)
saveScore(payload, match.params.id);
}
return topic.length > 0 ? (
<div className='container'>
{currentIndex >= topic.length ? (
<Fragment>
<SaveScoreForm topic={topic} score={score} />
<form
onSubmit={e => onSubmit(e)}
>
<input
type='hidden'
value={score}
onChange={(e) => onChange(e)}
/>
<input type='submit' className='btn btn-primary1 my-1' />
</form>
</Fragment>
) : (
<QuizItem
key={topic.question}
topic={topic[currentIndex]}
showAnswers={showAnswers}
handleNextQuestion={handleNextQuestion}
handleAnswer={handleAnswer}
/>
)}
</div>
) : (
<Spinner/>
)
}
Quiz.prototype = {
getTopicById: PropTypes.func.isRequired,
topic: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
topic: state.topic,
showAnswers: state.showAnswers,
handleNextQuestion: state.handleNextQuestion,
handleAnswer: state.handleAnswer
})
export default connect(mapStateToProps, { getTopicById })(Quiz)
Child component
import React from 'react'
export const SaveScoreForm = ({ score, topic, }) => {
return (
<div>
<div className='bg-primary1 p-2 my-4'>
<h1 className='large'>Review Your Score</h1>
<p className="lead">Quiz ended! Your score is: {(score/topic.length) * 100}%</p>
<p>Save your score to your profile or take the quiz again!</p>
</div>
</div>
);
};
export default SaveScoreForm;
TypeError: saveScore is not a function
Any help or pointers in the right direction would be very much appreciated.
Thanks
You are importing import { saveScore} from '../../actions/profile';
But then you have this prop
const Quiz = ({ getTopicById, saveScore
// ----------------------------^
which is overriding saveScore in your components context. Unless you are passing a saveScore prop while initialising <Quiz> it'll be undefined.
If you want to import the saveScore module just remove this prop variable.
I tried almost everything. I tested my API to ensure that the problem is not with it. It happens just one time when you visit the page. However, when you refresh it works fine.
Before Clicking delete:
Click here to see the image
After clicking delete button: Click here to see the image
Backend Route (home.route.js):
const express = require("express");
const mongoose = require("mongoose");
const Note = require("../models/note.model.js");
const router = express.Router();
router.get("/", (req, res) => {
Note.find()
.then(notes => res.json(notes))
.catch(err => res.status(400).json("Error: " + err));
});
router.post("/", (req, res) => {
const note = req.body;
const newNote = new Note(note);
newNote.save()
.then(() => res.json("Note added"))
.catch(err => res.status(400).json("Error: " + err));
});
router.delete("/", (req, res) => {
const idWeGotFromReact = req.body.noteId;
Note.findByIdAndDelete(idWeGotFromReact)
.then(() => res.json('Note deleted.'))
.catch(err => res.status(400).json('Error: ' + err));
})
module.exports = router;
React Code:
Code for the Note Component:
import React from "react";
import axios from 'axios';
import DeleteIcon from '#material-ui/icons/Delete';
function Note(props) {
function handleClick() {
const id = props.noteId;
axios({
method: 'delete',
url: 'http://localhost:5000',
data: {
noteId: id
}
});
props.onDelete(id);
}
return (
<div className="note">
<h1>{props.title}</h1>
<p>{props.content}</p>
<button name={props.noteId} onClick={handleClick}>
<DeleteIcon />
</button>
</div>
);
}
export default Note;
Code for the Main App component:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";
function App() {
const [notes, setNotes] = useState([]);
useEffect(() => {
axios
.get('http://localhost:5000')
.then(res => {
setNotes(res.data);
});
}, []);
function addNote(newNote) {
setNotes(prevNotes => {
return [...prevNotes, newNote];
});
}
function deleteNote(id) {
setNotes(notes => {
return notes.filter((noteItem) => {
return noteItem._id !== id;
});
});
}
function NoteList() {
return (
notes.map((noteItem) => {
return (
<Note
key={noteItem._id}
id={noteItem._id}
title={noteItem.title}
content={noteItem.content}
onDelete={deleteNote}
noteId={noteItem._id}
/>
);
})
);
}
return (
<div>
<Header />
<CreateArea onAdd={addNote} />
<NoteList />
<Footer />
</div>
);
}
export default App;
Input Component:
import React, { useState } from "react";
import axios from "axios";
function CreateArea(props) {
const [note, setNote] = useState({
title: "",
content: ""
});
function handleChange(event) {
const { name, value } = event.target;
setNote(prevNote => {
return {
...prevNote,
[name]: value
};
});
}
function submitNote(event) {
props.onAdd(note);
setNote({
title: "",
content: ""
});
event.preventDefault();
axios
.post('http://localhost:5000', note)
.then(res => {
console.log(res);
console.log(res.data);
});
}
return (
<div>
<form action="/" method="post">
<input
name="title"
onChange={handleChange}
value={note.title}
placeholder="Title"
/>
<textarea
name="content"
onChange={handleChange}
value={note.content}
placeholder="Take a note..."
rows="3"
/>
<button className="button" onClick={submitNote}>Add</button>
</form>
</div>
);
}
export default CreateArea;
I would also appreciate if you can provide a review of my code because I am a beginner and that would definitely help me.
Try this approach, (just an assumption)
function deleteNote(id) {
setNotes(notes => {
const filteredNotes = notes.filter((noteItem) => {
return noteItem._id !== id;
});
return [...filteredNotes];
});
}
I'm building a web app with React where I have a component (product.js), with a form connected to a db, and another component where I need to use the data inserted previously in the form. The form is working and is sending the info to the mongodb, but I'm struggling with getting the data to the last component (Output.js) where I need to access that data. The flow is from product.js to another comp, profile.js, and then to output.js. I'm surely missing or doing something wrong but so far haven't been able to make it work. Any help or suggestions on how to do it are greatly appreciated.
Product.js route:
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const Product = require('../models/product-model');
// POST route => to create a new product
router.post('/product', (req, res, next) => {
const { name, price, category } = req.body;
Product.create({
name,
price,
category
})
.then(response => {
res.json(response);
})
.catch(err => {
res.json(err);
});
});
// GET route => to retrieve a specific product
router.get('/product/:productId', (req, res, next) => {
Product.findById(req.params.productId)
.then(product => {
console.log("this is it>>>>>>>>>>>>>", product)
res.json(product);
})
.catch(error => {
res.json(error);
});
});
module.exports = router;
Product.js React component:
import React, {Component} from 'react';
import axios from 'axios';
class Products extends Component {
constructor(props){
super(props);
this.state = { name: "", price: "", category: "" };
}
handleFormSubmit = (event) => {
event.preventDefault();
this.props.history.push('/profile');
const name = this.state.name;
const price = this.state.price;
const category = this.state.category;
axios.post("http://localhost:5000/product", { name, price, category })
.then( () => {
this.props.getData();
console.log("added to db!");
this.setState({name: "", price: "", category: ""});
})
.catch( error => console.log(error) )
}
handleChange = (event) => {
const {name, value} = event.target;
this.setState({[name]: value});
}
render(){
return(
<div>
<form onSubmit={this.handleFormSubmit}>
<label>Name</label>
<input type="text" name="name" value={this.state.name} onChange={ e => this.handleChange(e)}/>
<label>Category</label>
<input type="text" name="category" value={this.state.category} onChange={ e => this.handleChange(e)}/>
<label>Price</label>
<input type="number" name="price" value={this.state.price} onChange={ e => this.handleChange(e)} />
<input type="submit" value="Submit" />
</form>
</div>
)
}
}
export default Products;
Output.js component:
import React, {Component} from 'react';
import axios from 'axios';
class Output extends Component {
constructor(props){
super(props);
this.state = {};
}
componentDidMount() {
this.getProduct();
}
getProduct = () => {
const params = this.props.match
console.log(this.props);
axios.get(`http://localhost:5000/product/:productId`)
.then( responseFromApi => {
console.log("this is it", responseFromApi);
const theProduct = responseFromApi.data;
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>this is the product", theProduct);
this.setState(theProduct);
})
.catch(err => console.log(err));
}
render() {
return (
<div>
<h1>{this.state.price}</h1>
<h1>results</h1>
</div>
)
}
}
export default Output;