I'm trying to save products in my MERN project. When I try to submit data I get this message
http://localhost:8000/api/product/create/5f4e7732333b2b21ec06a9f5 400 (Bad Request) and when I checked a response in the network it gives {"error":""} no error message it gives. Please review my code and guide me.
AddProduct.js
import React, {useState, useEffect} from 'react';
import Layout from '../core/Layout';
import {isAuthenticated} from '../auth';
import {createProduct, getCategories} from './apiAdmin';
const AddProduct = () => {
const [values, setValues] = useState({
name: '',
description: '',
price: '',
categories: [],
category: '',
shipping: '',
quantity: '',
photo: '',
loading: false,
error: '',
createProduct: '',
redirectToProfile: false,
formData: ''
});
const {user, token} = isAuthenticated();
const {
name,
description,
price,
categories,
category,
shipping,
quantity,
loading,
error,
createProducts,
redirectToProfile,
formData
} = values;
const init = () => {
getCategories().then(data => {
if(data.error){
setValues({...values, error: data.error})
} else{
setValues({...values, categories: data.data, formData: new FormData()});
}
});
};
useEffect(() => {
init();
}, []);
const handelChnage = name => event => {
const value = name === 'photo' ? event.target.files[0] : event.target.value
formData.set(name, value)
setValues({...values, [name]: value})
};
const clickSubmit = (event) => {
event.preventDefault();
setValues({...values, error: '', loading: true});
createProduct(user._id, token, formData).then(data =>{
if(data.error){
setValues({...values, error: data.error})
} else{
setValues({
...values,
name: '',
description: '',
photo: '',
price: '',
quantity: '',
loading: false,
createProduct: data.name
});
}
});
};
const newPostForm = () => (
<form className="mb-3" onSubmit={clickSubmit}>
<h4>Post Photo</h4>
<div className="form-group">
<label className="form-group">
<input onChange={handelChnage('photo')} type="file" name="photo" accept="image/*" />
</label>
</div>
<div className="form-group">
<label className="text-muted">Name</label>
<input onChange={handelChnage('name')} type="text" className="form-control" value={name} />
</div>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea onChange={handelChnage('description')} className="form-control" value={description} />
</div>
<div className="form-group">
<label className="text-muted">Price</label>
<input onChange={handelChnage('price')} type="number" className="form-control" value={price} />
</div>
<div className="form-group">
<label className="text-muted">Category</label>
<select onChange={handelChnage('category')} className="form-control" >
<option>Please Select</option>
{categories && categories.map((c,i) => (
<option key={i} value="{c._id}">
{c.name}
</option>
))}
</select>
</div>
<div className="form-group">
<label className="text-muted">Shipping</label>
<select onChange={handelChnage('shipping')} className="form-control" >
<option>Please Select</option>
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div className="form-group">
<label className="text-muted">Quantity</label>
<input onChange={handelChnage('quantity')} type="number" className="form-control" value={quantity} />
</div>
<button className="btn btn-outline-primary">Create Category</button>
</form>
);
const showError = () =>{
return(
<div className="alert alert-danger" style={{display: error ? '' : 'none'}}>
{error}
</div>
);
};
const showSuccess = () =>{
return(
<div className="alert alert-info" style={{display: createProducts ? '' : 'none'}}>
<h2>product is created!</h2>
</div>
);
};
const showLoading = () =>
loading && (
<div className="alert alert-info">
<h2>Loading...</h2>
</div>
);
return(
<Layout title="Add New Product" description={`Welcome ${user.name}!`} className="container-fluid" >
<div className="row">
<div className="col-8 offset-md-2">
{showLoading()}
{showSuccess()}
{showError()}
{newPostForm()}
</div>
</div>
</Layout>
);
};
export default AddProduct;
apiAdmin.js
export const createProduct = (userId, token, product) =>{
//console.log(name, photo, description, price, category, shipping, quantity);
const url = `http://localhost:8000/api/product/create/${userId}`;
//console.log(url);
return fetch(url, {
method: "POST",
headers:{
Accept: 'application/json',
Authorization : `Bearer ${token}`
},
body: product
})
.then(response => {
return response.json();
})
.catch(err =>{
console.log(err);
});
};
please help me
Thanks in advance
const [values, setValues] = useState({
name: '',
description: '',
price: '',
categories: [],
category: '',
shipping: '',
quantity: '',
photo: '',
loading: false,
error: '',
createdProduct: '', -> edit
redirectToProfile: false,
formData: ''
});
const {user, token} = isAuthenticated();
const {
name,
description,
price,
categories,
category,
shipping,
quantity,
loading,
error,
createdProduct, -> edit
redirectToProfile,
formData
} = values;
Related
I keep getting error "Warning: Each child in a list should have a unique "key" prop" on console log. I think there is something wrong in the
axios.delete('http://localhost:3000/contacts/${id}
' or
axios.put('http://localhost:3000/contacts/${isUpdate.id}'
It works, but does not configure in the json-server that I made. So the changes does not happen in the json-server.
The "save" button works, and added new data into my json-server. But, when I tried to edit, or delete, it does not save the changed in json-server.
My code:
import "./App.css";
import List from "./List";
import { useState,useEffect } from "react";
import {uid} from "uid";
import axios from "axios";
function App() {
const [contacts, setContacts] = useState([]);
function handleChange(e) {
let data = { ...formData };
data[e.target.name] = e.target.value;
setFormData(data);
}
const [isUpdate, setIsUpdate] = useState({ id: null, status: false});
const [formData, setFormData] = useState({
name: "",
telp: "",
});
useEffect(() => {
axios.get("http://localhost:3000/contacts").then((res) => {
console.log(res.data);
setContacts(res?.data ?? []);
});
}, []);
function handleSubmit(e){
e.preventDefault();
alert("Oke Bos!");
let data = [...contacts];
if(formData.name === "") {
return false;
}
if(formData.telp === "") {
return false;
}
if ( isUpdate.status){
data.forEach((contact) => {
if (contact.id === isUpdate.id) {
contact.name = formData.name;
contact.telp = formData.telp;
}
});
axios.put('http://localhost:3000/contacts/${isUpdate.id}', {
name: formData.name,
telp: formData.telp,
})
.then((res) => {
alert("Berhasil edit data!");
});
} else {
let newData = { id: uid(), name: formData.name, telp: formData.telp };
data.push(newData);
axios.post("http://localhost:3000/contacts", newData).then((res) => {
alert("Data telah disimpan cok!");
});
}
// tambah kontak yee
setIsUpdate({id: null, status: false});
setContacts(data);
setFormData({ name: "", telp: ""});
}
function handleEdit(id) {
let data = [...contacts];
let foundData = data.find((contact) => contact.id === id);
setFormData({ name: foundData.name, telp: foundData.telp});
setIsUpdate({id: id, status: true});
}
function handleDelete(id) {
let data = [...contacts];
let filteredData = data.filter((contact) => contact.id !== id);
axios.delete('http://localhost:3000/contacts/${id}').then((res) => {
alert("Data telah dihapus");
});
setContacts(filteredData);
}
return (
<div className="App">
<h1 className="px-3 py-3">My Contact List</h1>
<form onSubmit={handleSubmit} className="px-3 py-4">
<div className="form-group">
<label htmlFor="">Name</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.name}
name="name" />
</div>
<div className="form-group mt-3">
<label htmlFor="">No. Telp</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.telp}
name="telp" />
</div>
<div>
<button type="submit" className="btn btn-primary w-100 mt-3">
Save
</button>
</div>
</form>
<List handleDelete={handleDelete} handleEdit={handleEdit} data={contacts} />
</div>
);
}
export default App;
The list component:
import React from "react";
export default function List({data,handleEdit,handleDelete}) {
return (
<div className="list-group">
{
data.map((contact) => {
return (
<div className="list-group-item list-group-item-action">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-1">{contact.name}</h5>
<div>
<button onClick={() => handleEdit(contact.id)} className="btn btn-sm btn-link">Edit</button>
<button onClick={() => handleDelete(contact.id)} className="btn btn-sm btn-link">Del</button>
</div>
</div>
<p className="mb-1">{contact.telp}</p>
</div>
);
})}
</div>
);
}
I follow the tutorial, the code is like this, i checked it in so many times. But still it does not configure well into json-server like what i see on youtube.
I need to update options so that later useCallback will process it, but when I click on the checkbox, nothing changes.
But if you comment out setOptions, then the checkbox changes
const [options, setOptions] = useState({
s22: {value: 'TRUE', s: 22},
s23: {value: 'TRUE', s: 23},
s24: {value: 'TRUE', s: 24}
})
const changeFilter = event => {
setOptions({ ...options, [event.target.name]: {
value: event.target.checked.toString().toUpperCase(),
s: event.target.value
}
})
}
<div id="filter">
<p>
<label>
<input name="s22" type="checkbox" value="22" onChange={changeFilter} />
<span>УК</span>
</label>
</p>
<p>
<label>
<input name="s23" type="checkbox" value="23" onChange={changeFilter} />
<span>ФК</span>
</label>
</p>
<p>
<label>
<input name="s24" type="checkbox" value="24" onChange={changeFilter} />
<span>ФТ</span>
</label>
</p>
</div>
Found similar questions but there was a problem with preventDefault
Full code
import React, {useCallback, useContext, useEffect, useState} from 'react'
import {useHttp} from '../hooks/http.hook'
import {AuthContext} from '../context/AuthContext'
import {Loader} from '../components/Loader'
export const TreePage = () => {
const [tree, setTree] = useState([])
const [options, setOptions] = useState({
s22: {value: 'TRUE', s: 22},
s23: {value: 'TRUE', s: 23},
s24: {value: 'TRUE', s: 24}
})
const {loading, request} = useHttp()
const {token} = useContext(AuthContext)
const fetchTree = useCallback(async () => {
try {
const fetched = await request('/api/tree', 'GET', options, {
Authorization: `Bearer ${token}`
})
setTree(fetched)
} catch (e) {}
}, [token, request, options])
useEffect(() => {
fetchTree()
}, [fetchTree])
useEffect(() => {
var zoom = 1;
var zoomStep = 0.1;
document.getElementById("zoomIn").addEventListener("click",function(){
zoom += zoomStep; document.getElementById("zoomtext").style.transform = "scale("+zoom+")";
});
document.getElementById("zoomOut").addEventListener("click",function(){
if(zoom > zoomStep){
zoom -= zoomStep;
document.getElementById("zoomtext").style.transform = "scale("+zoom+")";
}
});
})
const changeFilter = event => {
setOptions({ ...options, [event.target.name]: {
value: event.target.checked.toString().toUpperCase(),
s: event.target.value
}
})
}
if (loading) {
return <Loader/>
}
return (
<>
{!loading &&
<div className="row">
<div className="col s6 offset-s3">
<div id="filter">
<p>
<label>
<input name="s22" type="checkbox" value="22" onChange={changeFilter} />
<span>УК</span>
</label>
</p>
<p>
<label>
<input name="s23" type="checkbox" value="23" onChange={changeFilter} />
<span>ФК</span>
</label>
</p>
<p>
<label>
<input name="s24" type="checkbox" value="24" onChange={changeFilter} />
<span>ФТ</span>
</label>
</p>
</div>
<div dangerouslySetInnerHTML={{__html: tree}}></div>
</div>
</div>
}
</>
)
}
I'm using SendGrid to send emails in my serverless Next.js project, deployed in Vercel, which works perfectly in development mode. But I'm having problems in production.
The error returned is:
contact-us-4c7332c1e7bfe2127d39.js:1 POST https://mywebsite.vercel.app/api/send 400
Yes, I enabled "Allow Less Secured Apps" in Google account and verify a Sender Identity in SendGrid.
Anybody experienced this kind of problem? How can I fix this?
This is the contact-us.js page
import Head from 'next/head'
import React, { useState } from 'react'
export default () => {
const [status, setStatus] = useState({
submitted: false,
submitting: false,
info: { error: false, msg: null }
})
const [inputs, setInputs] = useState({
name: '',
phone: '',
email: '',
message: ''
})
function SubmitButton(){
if (inputs.name && inputs.email && inputs.message) {
return <button type="submit" className="btn-submit" disabled={status.submitting}> {!status.submitting ? !status.submitted ? 'Submit' : 'Submitted' : 'Submitting...'} </button>
} else {
return <button type="submit" className="btn-submit" disabled>Submit</button>
};
};
const handleResponse = (status, msg) => {
if (status === 200) {
setStatus({
submitted: true,
submitting: false,
info: { error: false, msg: msg }
})
setInputs({
name: '',
phone: '',
email: '',
message: ''
})
} else {
setStatus({
info: { error: true, msg: msg }
})
}
}
const handleOnChange = e => {
e.persist()
setInputs(prev => ({
...prev,
[e.target.id]: e.target.value
}))
setStatus({
submitted: false,
submitting: false,
info: { error: false, msg: null }
})
}
const handleOnSubmit = async e => {
e.preventDefault()
setStatus(prevStatus => ({ ...prevStatus, submitting: true }))
const res = await fetch('/api/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(inputs)
})
const text = await res.text()
handleResponse(res.status, text)
}
return (
<div className="contact">
<main>
<div>
<h2>Get in touch!</h2>
<h3>How can we help you?</h3>
</div>
<form onSubmit={handleOnSubmit}>
<div className="form-group">
<input
id="name"
type="text"
name="name"
onChange={handleOnChange}
required
value={inputs.name}
className={inputs.name ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="name">Name</label>
</div>
<div className="form-group">
<input
id="email"
type="text"
name="email"
onChange={handleOnChange}
required
value={inputs.email}
className={inputs.email ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="email">Email</label>
</div>
<div className="form-group">
<input
id="phone"
type="tel"
name="phone"
onChange={handleOnChange}
required
value={inputs.phone}
className={inputs.phone ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="phone">Phone</label>
</div>
<div className="form-group">
<textarea
id="message"
onChange={handleOnChange}
required
value={inputs.message}
className={inputs.message ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="message">Message</label>
</div>
<SubmitButton />
{status.info.error && (
<div className="message-feedback error">
<p>Error: {status.info.msg}</p>
</div>
)}
{!status.info.error && status.info.msg && (
<div className="message-feedback success">
<p>Thanks for messaging us!</p>
<p>We'll get back to you soon.</p>
</div>
)}
</form>
</main>
</div>
)
}
And the /api/send.js
const sgMail = require('#sendgrid/mail')
export default async function(req, res) {
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
const { phone, email, message } = req.body
const msg = {
to: 'myemail#outlook.com', // Change to your recipient
from: 'mysenderemail#gmail.com', // Change to your verified sender
subject: `New Message From - ${email}`,
text: message,
html: `
<p>Phone: ${phone}</p>
<p>Sent from: ${email}</p>
<div>${message}</div>
`
}
try {
await sgMail.send(msg)
res.status(200).send('Message sent successfully.')
} catch (error) {
console.log('ERROR', error)
res.status(400).send('Message not sent.')
}
}
Thank you.
In my mern application I when trying to update the house information in my application I get this 400 bad request. The url shows [object%20Object] this next to the id in the which i believe is the result from the update function, but I don't know what is causing this error. the request works on the back-end, I've been using Postman to test all my routes and they are all successful. I also get this error 0.chunk.js:7824 Uncaught (in promise) Error: Request failed with status code 400 at createError (0.chunk.js:7824) I suspect this may have to do with how I try to update the data in my updateHouse function.
component editform
import React, { useState, useEffect } from "react";
// import axios from "axios";
import axios, {get, put} from 'axios'
import { Link, withRouter } from 'react-router-dom'
const EditHouseForm = (props) => {
// const initialState = {
// price: 0,
// city: '',
// county: '',
// numOfBeds: 0,
// numOfBaths: 0,
// numOfGarages: 0,
// isSaleOrRent: '',
// us_state: '',
// sqaurefeet: 0,
// house_image: 0,
// }
// const [house, setHouse] = useState(initialState)
const [house, setHouse] = useState({
id: '',
price: 0,
city: '',
county: '',
numOfBeds: 0,
numOfBaths: 0,
numOfGarages: 0,
isSaleOrRent: '',
us_state: '',
sqaurefeet: 0,
house_image: 0,
});
const [houseShow, setShowLoading] = useState(true);
const url = `http://localhost:5000/api/house-details/edit/${props.match.params.id}`;
useEffect(function() {
setShowLoading(false);
const fetchData = async () =>{
const result = await axios(`/api/house-details/${props.match.params.id}`);
setHouse(result.data);
console.log(result.data)
setShowLoading(false)
};
fetchData()
}, [])
// useEffect(function() {
// async function getHouse() {
// try {
// const response = await axios.get(url);
// setHouse(response.data);
// } catch(error) {
// console.log(error);
// }
// }
// getHouse();
// }, [props,url]);
const updateHouse = (e) =>{
setShowLoading(true);
e.preventDefault();
const data ={
price: house.price,
city: house.city,
county: house.county,
numOfBeds: house.numOfBeds,
numOfBaths: house.numOfBaths,
numOfGarages: house.numOfGarages,
isSaleOrRent: house.isSaleOrRent,
us_state: house.us_state,
sqaurefeet: house.sqaurefeet,
house_image: house.house_image
};
put(`/api/house-details/edit/${props.match.params.id}`, data).then((result)=>{
setShowLoading(false)
props.history.push(`/house-details/${result + props.match.params.id}`)
}).catch((error)=>{
setShowLoading(false)
console.log(error)
})
}
const onChange = (e) =>{
e.persist();
setHouse({...house, [ e.target.name]: e.target.value})
}
return (
<div>
<h1>hello world</h1>
<form className="form" onSubmit={updateHouse}>
<label> House Price</label>
<input type="number" placeholder="House Price"
onChange={onChange} defaultValue={house.price || undefined }
/>
<label >County</label>
<input type="text" placeholder="County"
onChange={onChange} defaultValue={house.county || ''}/>
<label >House Location(City)</label>
<input type="text" placeholder="City"
onChange={onChange} defaultValue={house.city || ''}
/>
<label>House Location(State)</label>
<input type="text" placeholder="State"
onChange={onChange} defaultValue={house.us_state || '' }
/>
<label>Sale or Rent</label>
<select onChange={onChange} defaultValue={house.isSaleOrRent || '' }>
<option>...</option>
<option value={`SALE`}>Sale</option>
<option value={`RENT`}>Rent</option>
</select>
<label >Sqft</label>
<input type="number" placeholder="sqft"
onChange={onChange} defaultValue={house.squarefeet || undefined }
/>
<label > Number of bedrooms</label>
<input type="number" placeholder="Number of bedrooms"
onChange={onChange} defaultValue={house.numOfBeds || undefined }
/>
<label> Number of bathrooms</label>
<input type="number" placeholder="Number of bathrooms"
onChange={onratechange} defaultValue={house.numOfBaths || undefined }
/>
<label > Number of garages</label>
<input type="number" placeholder="Number of garages"
onChange={onChange} defaultValue={house.numOfGarages || undefined}
/>
<label>House image</label>
<input type="file" placeholder="house image"
onChange={onChange}
/>
<button className="button" type="submit">Update</button>
</form>
</div>
);
};
export default withRouter(EditHouseForm);
back-end
router.put('/api/house-details/edit/:id', (req, res)=>{
House.findByIdAndUpdate(req.params.id, req.body).then(()=>{
res.status(200).end()
})
})
``
[1]: https://i.stack.imgur.com/OWPM4.png
Since result is an object and you're trying to concatenate it with a string, JS coerces the object to a string => '[object Object]'.
And it looks like you're getting a 400 Bad request when trying to fetch the house details with a malformed id in the URL (/api/house-details/[object%20Object]602ac5039b39c90015b3dc44).
props.history.push(`/house-details/${result + props.match.params.id}`)
should be
props.history.push(`/house-details/${props.match.params.id}`)
I am really a beginner in react and express. I did everything exactly as same as login, but in register it gives me "Uncaught (in promise) SyntaxError: Unexpected token r in JSON at position 0" this error.
This is my react code:
import React, { Component } from 'react';
class Register extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
name: ''
}
}
onEmailChange = (event) => {
this.setState({email: event.target.value})
}
onPasswordChange = (event) => {
this.setState({password: event.target.value})
}
onNameChange = (event) => {
this.setState({name: event.target.value})
}
onSubmitRegister = () => {
fetch('http://localhost:3101/register', {
method: "post",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
name: this.state.name,
email: this.state.email,
password: this.state.password
})
})
.then(response => response.json())
.then(data => {
console.log(data)
})
console.log('in')
}
render( props ) {
return (
<article className="br3 ba b--black-10 mv4 w-100 w-50-m w-25-l mw6 shadow-5 center">
<main className="pa4 black-80">
<div className="measure">
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<legend className="f4 fw6 ph0 mh0">Register</legend>
<div className="mt3">
<label className="db fw6 lh-copy f6" htmlfor="name">Email</label>
<input onChange = {this.onEmailChange} className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100" type="text" name="name" id="name" />
</div>
<div className="mt3">
<label className="db fw6 lh-copy f6" htmlfor="name">Name</label>
<input onChange = {this.onNameChange} className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100" type="email" name="email-address" id="email-address" />
</div>
<div className="mv3">
<label className="db fw6 lh-copy f6" htmlfor="password">Password</label>
<input onChange = {this.onPasswordChange} className="b pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100" type="password" name="password" id="password" />
</div>
</fieldset>
<div className="">
<input onClick = {this.onSubmitRegister} className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib" type="submit" value="Register" />
</div>
</div>
</main>
</article>
)
}
}
export default Register;
This is the server:
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(bodyParser.json());
app.use(cors());
const database = {
users: [
{
id: '123',
name: 'Zihan',
email: 'zihan#gmail.com',
password: 'booga',
entries: 0,
joined: new Date()
},
{
id: '124',
name: 'Shakib',
email: 'shakib#gmail.com',
password: 'choto',
entries: 0,
joined: new Date()
}
]
}
app.get('/', (req,res) => {
res.send(database.users);
})
app.post('/signin', (req,res) => {
if ( req.body.email === database.users[0].email && req.body.password === database.users[0].password ){
res.json('success');
}
else{
res.status(400).json('error logging in');
}
})
app.post('/register', (req,res) => {
const {name, email, password} = req.body;
database.users.push({
id: '134',
name: name,
email: email,
password: password,
entries: 0,
joined: new Date()
})
res.send('registrition sussessful')
})
app.get('/profile/:id', (req, res) => {
const { id } = req.params;
let found = false;
database.users.forEach(user => {
if(user.id === id) {
found = true;
return res.send(user);
}
})
if(!found){
res.status(404).json('not found')
}
})
app.put('/image', (req,res) => {
const { id } = req.body;
let found = false;
database.users.forEach(user => {
if(user.id === id) {
found = true;
user.entries++
return res.json(user.entries);
}
})
if(!found){
res.status(404).json('not found')
}
})
app.listen(3101, () => {
console.log('app is runing')
})
This is the console tab:
The error
This is the network tab:
This is response and it seems ok
As you can see my response is ok and I tested it by postman I am getting the registered user but react is throwing me the error.
Change this
res.send('registrition sussessful')
To this
res.json('registrition sussessful')
Or even better
res.status(200).send({message: "registration successful" })