axios duplicates post requests - node.js

I am currently finishing up with a MERN system and noticed this very weird bug , when i click submit in the react page the user is saved to Mongo db , a little bit later another user is saved with the same data.
Here is my code (React frontend)
import React from "react";
import withStyles from "#material-ui/core/styles/withStyles";
import InputLabel from "#material-ui/core/InputLabel";
// core components
import GridItem from "components/Grid/GridItem.jsx";
import GridContainer from "components/Grid/GridContainer.jsx";
import CustomInput from "components/CustomInput/CustomInput.jsx";
import Button from "components/CustomButtons/Button.jsx";
import Card from "components/Card/Card.jsx";
import CardHeader from "components/Card/CardHeader.jsx";
import CardAvatar from "components/Card/CardAvatar.jsx";
import CardBody from "components/Card/CardBody.jsx";
import CardFooter from "components/Card/CardFooter.jsx";
import axios from 'axios';
import avatar from "assets/img/faces/marc.jpg";
import Styles from './Styles'
import { Form, Field } from 'react-final-form'
const styles = {
cardCategoryWhite: {
color: "rgba(255,255,255,.62)",
margin: "0",
fontSize: "14px",
marginTop: "0",
marginBottom: "0"
},
cardTitleWhite: {
color: "#FFFFFF",
marginTop: "0px",
minHeight: "auto",
fontWeight: "300",
fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif",
marginBottom: "3px",
textDecoration: "none"
}
};
class UserProfile extends React.Component {
onChange = (e) => {
/*
Because we named the inputs to match their
corresponding values in state, it's
super easy to update the state
*/
this.setState({ [e.target.name]: e.target.value });
console.log('data', this.state.name)
}
onSubmit = async (values , e) => {
alert('User Created ')
let data = values;
axios.post('/api/users/newuser', {data})
.then(result => console.log(result))
.catch(err => console.log(err))
}
state = {
id: '',
name: "",
address:"",
phonenumber: "",
isp: "",
account: "",
accounttype: "",
paid: '',
staticip:'',
staticipdate: Date,
bill: '',
balance: '',
username: '',
pass: '',
apip: ''
render(){
return <div>
<h1>Create New User</h1>
<h3>Unlimitik POS system V1.0</h3>
<Form
onSubmit={this.onSubmit}
initialValues={{ }}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<div>
<label>Full Name</label>
<Field
name="name"
component="input"
type="text"
placeholder="Full Name"
/>
</div>
<div>
<label>Address</label>
<Field
name="address"
component="input"
type="text"
placeholder="address"
/>
</div>
<div>
<label>Phone Number</label>
<Field
name="phonenumber"
component="input"
type="text"
placeholder="phonenumber"
/>
</div>
<div>
<label>ISP</label>
<Field
name="isp"
component="input"
type="text"
placeholder="isp"
/>
</div>
<div>
<label>Account</label>
<Field
name="account"
component="input"
type="text"
placeholder="account"
/>
</div>
<div>
<label>Account Type</label>
<Field
name="accounttype"
component="input"
type="text"
placeholder="accounttype"
/>
</div>
<div>
<label>Paid</label>
<Field
name="paid"
component="input"
type="text"
placeholder="paid"
/>
</div>
<div>
<label>Static IP</label>
<Field
name="staticip"
component="input"
type="text"
placeholder="staticip"
/>
</div>
<div>
<label>Static IP Date</label>
<Field
name="staticipdate"
component="input"
type="date"
placeholder="staticipdate"
/>
</div>
<div>
<label>Bill</label>
<Field
name="bill"
component="input"
type="text"
placeholder="bill"
/>
</div>
<div>
<label>Balance</label>
<Field
name="balance"
component="input"
type="text"
placeholder="balance"
/>
</div>
<div>
<label>username</label>
<Field
name="username"
component="input"
type="text"
placeholder="username"
/>
</div>
<div>
<label>pass</label>
<Field
name="pass"
component="input"
type="text"
placeholder="pass"
/>
</div>
<div>
<label>AP / IP</label>
<Field
name="apip"
component="input"
type="text"
placeholder="AP / IP"
/>
</div>
<div>
<label>Notes</label>
<Field name="notes" component="textarea" placeholder="Notes" />
</div>
<div className="buttons">
<button type="submit" disabled={submitting || pristine} >
Submit
</button>
<button
type="button"
onClick={form.reset}
>
Reset
</button>
</div>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>
export default UserProfile;
What is happening is the request is saved in mongodb after 2 or 3 seconds ( no exact timing ) another request is send and a document is saved 2 times.
here is the route express.js
router.post('/newuser', async (req, res) => {
var x = Math.floor(Math.random() * Date.now() * 0.000000002);
const data = new User ({
id: x,
name: req.body.data.name,
address: req.body.data.address,
phonenumber: req.body.data.phonenumber,
isp: req.body.data.isp,
account: req.body.data.account,
accounttype: req.body.data.accounttype,
paid: req.body.data.paid,
staticip: req.body.data.staticip,
staticipdate: req.body.data.staticipdate,
bill: req.body.data.bill,
balance: req.body.data.balance,
username: req.body.data.username,
pass: req.body.data.pass,
apip: req.body.data.apip
} )
data.save()
.then(r => console.log(r))
.catch(err => console.log(err))
})
the log after (the ids are different since it is generated on backend not by form)

You seem to have 2 onSubmit handlers.
I would suggest removing one of them:
<Form
// onSubmit={this.onSubmit} <--- remove this line
initialValues={{ }}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>

Related

Path validation error when pushing in react but works in postman/node directly

I am trying to push info from my sign up page . I can display it and even get an error 500 but i see a path validation even though i can directly post from postman to my db. Here is my signUp page . My model and route is written all the same so i dont understand
import React from "react";
import {
MDBBtn,
MDBContainer,
MDBRow,
MDBCol,
MDBCard,
MDBCardBody,
MDBCardImage,
MDBInput,
MDBIcon,
MDBCheckbox,
} from "mdb-react-ui-kit";
import Navbar from "./Navbar";
import Footer from "./Footer";
import {useState} from "react";
// const initFormData = Object({
// //declaration de l'objet initiale pour recevoir les credentials
// username: "",
// email: "",
// password: "",
// // passwordCheck: "",ls
// });
const SignUpForm = () => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const collectData = async () => {
console.warn("warn" , username,email,password)
let result = await fetch("http://localhost:8000/api/auth/register",{
method: "post",
body: JSON.stringify({username,email,password}),
headers:{
'Content-type':'shop/JSON'
}
});
result = await result.json();
console.warn(result);
}
return (
<>
<Navbar />
<MDBContainer fluid>
<MDBCard className="text-black m-5" style={{borderRadius: "25px"}}>
<MDBCardBody>
<MDBRow>
<MDBCol
md="10"
lg="6"
className="order-2 order-lg-1 d-flex flex-column align-items-center"
>
<p className="text-center h1 fw-bold mb-5 mx-1 mx-md-4 mt-4">
Sign up
</p>
<div className="d-flex flex-row align-items-center mb-4 ">
<MDBIcon fas icon="user me-3" size="lg" />
<MDBInput
label="Votre Nom"
id="form1"
type="text"
className="w-100"
value={username}
onChange={(e) => setUsername("username", e.target.value)}
/>
</div>
<div className="d-flex flex-row align-items-center mb-4 ">
<MDBIcon fas icon="user me-3" size="lg" />
<MDBInput
label="Email"
id="email"
type="email"
className="w-100"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="d-flex flex-row align-items-center mb-4">
<MDBIcon fas icon="lock me-3" size="lg" />
<MDBInput
label="Mot de passe"
id="form3"
type="password"
name="password"
value={password}
onChange={(e) => setPassword("password" , e.target.value)}
/>
</div>
<div className="mb-4">
<MDBCheckbox
name="flexCheck"
value=""
id="flexCheckDefault"
label="Subscribe to our newsletter"
/>
</div>
<MDBBtn className="mb-4" size="lg" onClick={collectData()}>
Register
</MDBBtn>
</MDBCol>
<MDBCol
md="10"
lg="6"
className="order-1 order-lg-2 d-flex align-items-center"
>
<MDBCardImage
src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-registration/draw1.webp"
fluid
/>
</MDBCol>
</MDBRow>
</MDBCardBody>
</MDBCard>
</MDBContainer>
<Footer />
</>
);
};
export default SignUpForm;
i expected to be able to push but i get

push array from form reactjs

Hello i want asking about pushing array from form
This is sample my code post form to id
how to turn bellow form from post to id, to push to array.
function handleName(e) {
setInputForm({ ...inputForm, nama: e.target.value });
}
function handleJam(e) {
setInputForm({ ...inputForm, jam: e.target.value });
}
{formMode !== "" && (
<div id="form" className="card py-2 my-3 bg-secondary">
<div className="card-body">
<h4>Add </h4>
<form className="row" onSubmit={submitForm}>
<div className="col-5">
<input
type="text"
name="nama"
className="form-control mx-2"
placeholder="nama..."
value={inputForm.nama || ""}
onChange={handleName}
/>
</div>
<div className="col-2">
<input
type="text"
name="jam"
className="form-control mx-2"
placeholder="Jam ..."
value={inputForm.jam || ""}
onChange={handleJam}
/>
</div>
<div className="col-2">
<input
type="submit"
className="btn btn-success"
value="Send"
/>
</div>
</form>
</div>
</div>
)}
i can use push on postman with this way
put -> localhost:4000/kelas/update/:id
{
"$push":{
"jadwal":
[
{
"nama":"Susanti",
"jam":"12"
}
]
}
}

Empty JEST test taking over 200 seconds

I have a two test suites. One actually makes API calls, and seems to run in about 20 seconds. Other one, is literally empty and takes over 248 seconds. Two of the tests are todo, and one had some implementation that I commented out. It's still taking forever. Why is this?
import { render, waitFor, screen } from "#testing-library/react";
import MyContent from "./MyContent.js";
describe('MyContent Component', () => {
it.todo('should call API when search button is clicked');
it('should render some text when api responds', () => {
/*
render(<MyContent />);
await waitFor(() => {
screen.getByText("some text");
});
*/
});
it.todo('should render error message when api fails');
});
Here is my jest config defined inside package.json
"jest": {
"transform": {
"^.+\\.[t|j]sx?$": "babel-jest"
},
"testEnvironment": "jsdom"
},
I need to use jsdom because there is a window.location in existing code.
Update: Adding component code
import React, { useState } from "react";
import { Input } from "#progress/kendo-react-inputs";
import { Label } from "#progress/kendo-react-labels";
import * as Constants from "../common/Constants.js";
import SearchTextBox from "../../components/SearchTextbox/SearchTextbox.js";
import someService from "../../services/someService.js";
import { Update } from "#material-ui/icons";
function MyContent(props) {
const isThatPage = props.pageIdentifier == Constants.PageIdentifier.thatPage;
const [eDetailsOutput, seteDetailsOutput] = useState({
a: null,
b: null,
c: null,
d: null
});
const handleChange = (e) => {
let dataToPush = [];
dataToPush.push({ key: e.target.name, value: e.target.value });
if (props.handleChange) {
props.handleChange(dataToPush);
}
};
const thatInput = {
q: null,
w: null,
eId: null,
x: null,
z: props.z
};
const handleSearchClick = () => {
someService.getthatDetailsBya(thatInput)
.then((response) => {
let updatedValue = {};
updatedValue = {
a: response?.eDetails.a,
b: response?.eDetails.b,
c: response?.eDetails.c,
d: response?.eDetails.d
}
seteDetailsOutput(eDetailsOutput => ({
...eDetailsOutput,
...updatedValue
}));
})
.catch((error) => {
goToAPIErrorPage(error?.message);
});
};
return (
<div className="k-form form_margin">
<div className="k-geo-form">
<div className="card">
<div className="card-item">
<div className="row">
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>el Name</Label>
{isThatPage ? (
<SearchTextBox
id="z-textbox"
name="z"
value={props.z ?? ""}
handleChange={handleChange}
readOnly={props.isReadOnly}
handleSearchClick={handleSearchClick}
/>
) : (
<Input
id="z-textbox"
name="z"
value={props.z ?? ""}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
)}
</div>
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>a</Label>
{isThatPage ? (
<SearchTextBox
id="a-textbox"
name="a"
// value={props.a ?? ""}
value={eDetailsOutput.a ?? "aIII"}
handleChange={handleChange}
readOnly={props.isReadOnly}
handleSearchClick={handleSearchClick}
/>
) : (
<Input
id="a-textbox"
name="a"
value={props.a ?? ""}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
)}
</div>
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>Entity Category Type</Label>
<Input
id="b-textbox"
name="b"
// value={props.b ?? ""}
value={eDetailsOutput.b ?? "beee"}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
</div>
</div>
<div className="row">
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>Status</Label>
<Input
id="Status-textbox"
name="Status"
// value={props.Status ?? ""}
value={eDetailsOutput.c ?? "csssss"}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
</div>
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>Other Status</Label>
<Input
id="OtherStatus-textbox"
name="OtherStatus"
value={props.OtherStatus ?? ""}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
</div>
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>Some Role</Label>
<Input
id="Role-textbox"
name="Role"
value={props.Role ?? ""}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
</div>
</div>
<div className="row">
<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>Some Type</Label>
<Input
id="Type-textbox"
name="Type"
value={eDetailsOutput.d ?? "deeeeee"}
onChange={handleChange}
className={props.isReadOnly ? "readOnlyInput" : ""}
readonly={props.isReadOnly}
/>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default MyContent;

Trying to display IMG with src set to Binary/Buffer image data from Mongoose

Trying to display IMGs with React/JSX with Buffered/Binary data saved to my MongoDB/Mongoose database.
i iterate over the data array with the IMG element looking like this:
<img src={`data:${item.img.contentType};base64,${item.img.data.data.toString("base64")}`} alt="" />
import React, { useState, useEffect } from "react";
import axios from "axios";
const FilesUpload = () => {
const [allPics, setAllPics] = useState([]);
useEffect(() => {
const getPics = async () => {
let res = await axios.get("http://localhost:8080/");
setAllPics(res.data);
};
// query the server for all of the picture objects
getPics();
}, []);
const [state, setState] = useState({});
const handleChange = (e) => {
e.preventDefault();
setState(e.target.value);
console.log(state);
};
return (
<>
<h1>upload an image</h1>
<hr />
<div>
<form
action="http://localhost:8080/"
method="POST"
encType="multipart/form-data"
>
<div>
<label>Image Title</label>
<input type="text" id="name" placeholder="Name" name="name" onChange={handleChange} value={state.name}/>
</div>
<div>
<label htmlFor="desc">Image Description</label>
<textarea id="desc" name="desc" rows="2" placeholder="Description"
onChange={handleChange} value={state.desc}/>
</div>
<div>
<label htmlFor="image">Upload Image</label>
<input type="file" id="image" name="image" required />
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
{allPics.length > 0 ? (
<div>
{allPics.map((item, index) => (
<div key={index}>
<div>
<img src={`data:${item.img.contentType};base64,${item.img.data.data.toString("base64")}`} alt="" />
</div>
</div>
))}
</div>
) : (
<>
<hr />
<br />
<h1>uploaded files</h1>
<h5>Loading..</h5>
</>
)}
</>
);
};
export default FilesUpload;
but I always get ERR_INVALID_URL:
from similar threads on the net I've read that I need to take those comma-delimitated values and remove the comma which will give me the proper data. having a hard time figuring that out. any help would be great. thanks
I was facing the same problem after saving image like this in my mongoose model and after many research I resolved this, hope this works for you also
const base64String = btoa(String.fromCharCode(...new Uint8Array(item.img.data.data)));
and in img tag put this -:
src={`data:image/${item?.img?.contentType};base64,${base64String}`}

can't upload images using react to backend using axios and nodejs

I try to upload a photo from React and save it in a public folder on the backend and then display the filename in the MySql database
After trying it through Postman, the photo has been successfully uploaded and appears and produces a json like this
{"image":"/img/14d714a9ed97fb92db657b9518e89a1e.png",
"id_produk":23,
"id_user":19,
"Nama_toko":"Nihongo Mantappu",
"Nama_Produk":"Butter",
"Deskripsi":"Mentega Blueband 50g",
"Price":5000,
"Jumlah_stock":7},
but when I tried it in React it only produced this
{"image":"/img/",
"id_produk":29,
"id_user":19,
"Nama_toko":"Nihongo Mantappu",
"Nama_Produk":"Beras Cinajur",
"Deskripsi":"Beras Cianjur 1kg",
"Price":500000,"Jumlah_stock":20}
so that when i check the database on the image it becomes empty
here the code for upload image
import React from 'react'
import jwt_decode from 'jwt-decode';
import 'bootstrap/dist/css/bootstrap.min.css';
import NavbarPenjual from '../../Component/NavbarPenjual';
import {addproduk} from '../../View/UserFunctions';
import { Form,Col, Button } from 'react-bootstrap';
class TambahProduk extends React.Component{
constructor(){
super()
this.state={
id_user:'',
Nama_toko:'',
Nama_produk: '',
Harga:'',
image: '',
Deskripsi: '',
Jumlah_produk: '',
error:{}
}
this.onChange=this.onChange.bind(this)
this.onSubmit=this.onSubmit.bind(this)
}
onChange(e){
this.setState({[e.target.name]:e.target.value})
}
componentDidMount(){
const token = localStorage.getItem('usertoken')
const decoded= token ? jwt_decode(token) : null;
this.setState({
id_user:decoded.id_user,
Nama_toko:decoded.Nama_toko
})
}
onSubmit(e){
e.preventDefault()
const newProduk={
id_user:this.state.id_user,
Nama_toko:this.state.Nama_toko,
Nama_Produk: this.state.Nama_Produk,
Price:this.state.Price,
image: this.state.image,
Deskripsi: this.state.Deskripsi,
Jumlah_stock: this.state.Jumlah_stock,
}
console.log(newProduk)
addproduk(newProduk).then(res =>{
//localStorage.setItem('usertoken',res.data.token);
this.props.history.push(`/DashboardPenjual`)
}).catch(err=>{
console.log(err)
alert("gagal")
})
}
render(){
return(
<div>
<NavbarPenjual/>
<Form className="container"style={{marginTop:28}} noValidate onSubmit={this.onSubmit}>
<h2>Tambah Produk</h2>
<Form.Row controlId="exampleForm.ControlInput1">
<Form.Label column lg={2}>
Nama Produk
</Form.Label>
<br/>
<Col>
<Form.Control
type="text"
placeholder="Masukan Nama Produk"
name="Nama_Produk"
value={this.state.Nama_Produk}
onChange={this.onChange}
/>
</Col>
</Form.Row>
<br/>
<Form.Row controlId="exampleForm.ControlInput1">
<Form.Label column lg={2}>
Harga Produk
</Form.Label>
<br/>
<Col>
<Form.Control type="text"
placeholder="Masukan Harga Produk"
name="Price"
value={this.state.Price}
onChange={this.onChange}
/>
</Col>
</Form.Row>
<br/>
<Form.Row controlId="exampleForm.ControlInput1">
<Form.Label column lg={2}>
Jumlah Produk
</Form.Label>
<br/>
<Col>
<Form.Control
type="text"
placeholder="Masukan Jumlah Produk"
name="Jumlah_stock"
value={this.state.Jumlah_stock}
onChange={this.onChange}
/>
</Col>
</Form.Row>
<br/>
<Form.Row controlId="exampleForm.ControlInput1">
<Col>
<Form.Group controlId="exampleForm.ControlTextarea1">
<Form.Label>Deskripsi Produk</Form.Label>
<br/>
<Form.Control
as="textarea"
rows="3"
name="Deskripsi"
value={this.state.Deskripsi}
onChange={this.onChange}
/>
</Form.Group>
</Col>
</Form.Row>
<br/>
<Form.Row controlId="exampleForm.ControlInput1">
<Form.Group>
<Form.File
id="exampleFormControlFile1"
label="Masukan Foto Produk"
type="image"
name="image"
value={this.state.image}
onChange={this.onChange}
/>
</Form.Group>
</Form.Row>
<br/>
<button
type="submit"
className="btn btn-lg btn-primary btn-block"
>Submit</button>
<Form.Row controlId="exampleForm.ControlInput1" style={{ visibility: "hidden" }}>
<Col>
<Form.Group controlId="exampleForm.ControlInput1">
<br/>
<Form.Control
as="text"
name="id_user"
value={this.state.id_user}
onChange={this.onChange}
/>
</Form.Group>
</Col>
</Form.Row>
<Form.Row controlId="exampleForm.ControlInput1" style={{ visibility: "hidden" }}>
<Col>
<Form.Group controlId="exampleForm.ControlTextarea1">
<br/>
<Form.Control disabled
as="area"
name="Nama_toko"
value={this.state.Nama_toko}
onChange={this.onChange}
/>
</Form.Group>
</Col>
</Form.Row>
</Form>
</div>
)
}
}
export default TambahProduk;
this is part of the axios userfuction for add product
export const addproduk = newProduk =>{
return axios
.post('product/addproduk',{
id_user:newProduk.id_user,
Nama_toko:newProduk.Nama_toko,
Nama_Produk:newProduk.Nama_Produk,
image: newProduk.image,
Deskripsi:newProduk.Deskripsi,
Price:newProduk.Price,
Jumlah_stock:newProduk.Jumlah_stock
})
.then(res=>{
console.log("produk di tambahkan")
return res
})
.catch(err=>{
console.log(err);
return err;
})
}
How do I get uploaded like when I use Postman?
Image is not an value, it's a file. So, in the onChange function you assigned the image.target.name as value
Try like this :
event.target.name === "image"? event.target.files[0] : event.target.value;

Resources