How to create onSubmit with Material-UI - node.js

So I'm fairly new to node.js / react / material-ui. I've been following a guide to try setting up a website and have been getting on pretty well. I decided to include material-ui for snazzy components (not part of the guide) and then got stuck because I can't seem to fire custom functions whilst using a themed ui.
With the below code, I can create everything fine if I ditch the 'classes' props. I can add my function and everything works. But I obviously lose all my styling if I do this.
const styles = theme => ({
// Styling - omitted
});
const Login = (props) => {
const {classes} = props;
return(
<div>
<Paper className={classes.root}>
<form className={classes.container} noValidate autoComplete="off">
<TextField
id="email"
label="Email"
className={classes.textField}
InputProps={{
className: classes.input
}}
type="email"
name="email"
autoComplete="email"
margin="normal"
variant="outlined"
required
autoFocus
/>
<TextField
id="outlined"
label="Password"
className={classes.textField}
InputProps={{
className: classes.input
}}
type="password"
autoComplete="current-password"
margin="normal"
variant="outlined"
required
/>
<Typography className={classes.divider} />
<Button
type="submit"
variant="contained"
color="inherit"
className={classes.button}
>
Login
</Button>
</form>
</Paper>
</div>
);
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Login);
I'm trying to combine the styling as well as being able to fire a custom function to submit the form data. Does anyone have any thoughts?

The class property/ styles shouldn't have any effect on form submission custom function. If you think that ditching the 'class props' you can get a custom function to work - post your code so we can help you further. [Your code is missing submit function]
Here is one way to add custom submit function
const Login = (props) => {
const {classes} = props;
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
function handleSubmit(event) {
event.preventDefault();
console.log( 'Email:', email, 'Password: ', password);
// You should see email and password in console.
// ..code to submit form to backend here...
}
return( <div >
<Paper className={classes.root}>
<form className={classes.container} onSubmit={handleSubmit} >
<TextField
....
value={email}
onInput={ e=>setEmail(e.target.value)}
.....
/>
<TextField
....
value={password}
onInput={ e=>setPassword(e.target.value)}
....
/>
<Typography className={classes.divider} />
<Button
type="submit"
....
className={classes.button}
>
Login
</Button>
</form>
</Paper>
</div>
);

Related

.map() React undefined - Axios & Express

Keep getting this error when trying to submit a form in React
Uncaught TypeError: queryList.map is not a function
This is the code:
const [query, setQuery] = useState();
const [queryList, setQueryList] = useState([]);
const [response, setResponse] = useState([]);
const [responseList, setResponseList] = useState([]);
const createQuery = () =>{
setQueryList(
{query}
);
alert(queryList)
Axios.post('http://localhost:3001/createQuery', {
query
}).then((res)=>{
setResponse(res)
setResponseList(...responseList, {res})
})
}
return(
<div>
{queryList && queryList.map((e) => {
return(
<p className="ml-52 text-white text-xl">{e.query}</p>
)
})}
<form>
<textarea onChange={(event)=>{
setQuery(event.target.value)
}}
type="text" name="name" autoComplete="off" placeholder="Ask a question" className = "caret-gray-200 bg-gray-800 shadow-md h-20 w-5/6 inset-x-0 bottom-6 absolute left-36 items-center snap-center text-xl p-6" />
<button onClick={createQuery} type="submit" name="submit" className="text-white inset-x-0 bottom-6 absolute bg-transparent w-20 h-20 ml-auto mr-28 focus:outline-none focus:none">
<AiOutlineSend size="28" />
</button>
</form>
</div>
)
After I submit the form, I need the query mapped
I know I didn't mention any other errors, but if you see them, please let me know!
By the way, all the other posts didn't work for me.
Thanks :)
When you set the queryList you will need to set it to an array by using array brackets. Also by the name i'm assuming you want an array of all queries so you will need to include previous queries that are already stored in queryList.
setQueryList([...queryList, { query }]);
This is what your setter function should look like.
Aside from this the alert function will not work since queryList is not updated in time to be used so I would recommend you to just use query in alert instead of queryList.
Also because of the way you use forms the page will be redirected, this is solved by using onSubmit event and using the preventDefault() function.
const [query, setQuery] = useState();
const [queryList, setQueryList] = useState([]);
const [response, setResponse] = useState();
const [responseList, setResponseList] = useState([]);
const createQuery = (event) => {
event.preventDefault();
setQueryList([...queryList, { query }]);
alert(query);
Axios.post('http://localhost:3001/createQuery', {
query,
}).then((res) => {
setResponse(res);
setResponseList(...responseList, { res });
});
};
return (
<div>
{queryList &&
queryList.map((e) => {
return (
<p className='ml-52 text-white text-xl'>{e.query}</p>
);
})}
<form onSubmit={createQuery}>
<textarea
onChange={(event) => {
setQuery(event.target.value);
}}
type='text'
name='name'
autoComplete='off'
placeholder='Ask a question'
className='caret-gray-200 bg-gray-800 shadow-md h-20 w-5/6 inset-x-0 bottom-6 absolute left-36 items-center snap-center text-xl p-6'
/>
<button
type='submit'
name='submit'
className='text-white inset-x-0 bottom-6 absolute bg-transparent w-20 h-20 ml-auto mr-28 focus:outline-none focus:none'
/>
</form>
</div>
);
I have not tested anything with axios but this code should work.

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

How can I display my response messages that I send in node js on my frontend with Reactjs

I am trying to build a basic login/signup app with the mern stack.I am new to it. While making the backend with node and express I have added lot of json messages in the code like-
return res.status(400).json({message:"Unable to find user by this id"})
return res.status(404).json({message:"User doesnt exist"});
How can I display this json data to my frontend with react?
This is the handleSubmit code-
const handleSubmit=(e)=>{
e.preventDefault()
console.log(inputs);
if(isSignup){
sendRequest("signup")
.then((data)=>localStorage.setItem("userId",data.user._id))
.then(()=>dispath(authActions.login()))
.then(()=>navigate("/blogs"))
}else{
sendRequest()
.then((data)=>localStorage.setItem("userId",data.user._id))
.then(()=>dispath(authActions.login()))
.then(()=>navigate("/blogs"))
.then(data=>console.log(data))
}
}
This is the return div code-
<form onSubmit={handleSubmit}>
<Box display="flex" flexDirection={'column'}
alignItems='center'
maxWidth={400}
justifyContent={'center'}
boxShadow="10px 10px 20px #ccc"
padding={3}
margin="auto"
marginTop={5}
borderRaidus={5}>
<Typography variant="h2" padding={3} textAlign="center">{isSignup?"Signup":"Login"}</Typography>
{isSignup && <TextField name="name" onChange={handleChange} value={inputs.name} placeholder='name' margin="normal"/>}
<TextField name="email" onChange={handleChange} value={inputs.email} type={'email'} placeholder='email' margin='normal'/>
<TextField name="password" onChange={handleChange} value={inputs.password} type={'password'} placeholder='password' margin='normal'/>
<Button type={"submit"} variant="contained" sx={{borderRadius:3,marginTop:3}} color="warning">Submit</Button>
<Button onClick={()=>setIsSignup(!isSignup)} sx={{borderRadius:3,marginTop:3}}>
Change to {isSignup ?"Login":"Signup"}</Button>
</Box>
</form>
</div>
)
}
export default Auth
Just try this one.
const handleSubmit = async(...) => {
...
try{
const response = await axios.post(...);
const data = await response.json();
console.log(data);
}catch(){
...
}
}

Error in App.js when trying to launch local React testing when switching to using hooks

I'm working on a project for my internet programming class and I'm not quite sure where I made my mistake here. I had this project at least running and able to test locally up until last night when I switched to using hooks (or trying to anyway). When I run npm start this is what logs into the console on Firefox.
Uncaught TypeError: this is undefined
App App.js:67
React 11
workLoop scheduler.development.js:266
flushWork scheduler.development.js:239
performWorkUntilDeadline scheduler.development.js:533
js scheduler.development.js:571
js scheduler.development.js:633
factory react refresh:6
Webpack 24
App.js:67
App App.js:67
React 11
performConcurrentWorkOnRoot self-hosted:1406
workLoop scheduler.development.js:266
flushWork scheduler.development.js:239
performWorkUntilDeadline scheduler.development.js:533
(Async: EventHandlerNonNull)
js scheduler.development.js:571
js scheduler.development.js:633
factory react refresh:6
Webpack 24
I had not changed any of my import statements, I had only added useState. VSCode shows me no errors in my code, so I believe something is out of place, but that's why I'm here to ask.
//import logo from './logo.svg';
import './App.css';
import './form.css';
import React, { useState } from 'react';
function App(){
const [showText, setShowText] = useState(0);
const radioHandler = (showText) => {
setShowText(showText);
};
// constructor = (props) => {
// super(props);
// this.state = {
// status: 0
// };
// handleInputChange = handleInputChange.bind(this);
// handleSubmit = handleSubmit.bind(this);
// }
const handleInputChange = (event, value) => {
console.log(value);
}
const handleSubmit = (event) => {
event.preventDefault();
}
return (
<div className="form_css">
<form onSubmit={handleSubmit}>
<div className="general_info_container">
<div className="name_container">
<label className="f_name">First Name:</label>
<input
name="f_name"
type="text"
value={this.state.f_name}
onChange={handleInputChange}
placeholder="Please enter your first name"
/>
<label className="m_name">Middle Initial:</label>
<input
name="m_name"
type="text"
value={this.state.m_name}
onChange={handleInputChange}
placeholder="Please enter your middle initial"
/>
<label className="l_name">Last Name:</label>
<input
name="l_name"
type="text"
value={this.state.l_name}
onChange={handleInputChange}
placeholder="Please enter your last name"
/>
</div>
<div className="address_container">
<label>Street:</label>
<input
className="street"
type="text"
value={this.state.street}
onChange={handleInputChange}
placeholder="123 Main Street"
/>
<label>City:</label>
<input
className="city"
type="text"
value={this.state.city}
onChange={handleInputChange}
placeholder="City Name"
/>
<label>State:</label>
<input
className="state"
type="text"
value={this.state.state}
onChange={handleInputChange}
placeholder="New York"
/>
<label>Zip Code:</label>
<input
className="zip_code"
type="number"
value={this.state.zip_code}
onChange={handleInputChange}
placeholder="12345"
/>
</div>
<div>
<label>
Have you exercised regularly within the past six (6) months?
</label>
<input
className="exr_yes"
type="radio"
value="true"
onChange={handleInputChange}
/>
<input
className="exr_no"
type="radio"
value="false"
onChange={handleInputChange}
/>
<br></br>
{/* Testing radio button hide/show */}
<label>Do you have any chonic medical conditions? TEST TEST TEST TEST TEST TEST</label>
<input
className="chronic_yes"
type="radio"
value="true"
checked={showText === 1}
onClick={(e) => radioHandler(1)}
/>
<input
className="chronic_no"
type="radio"
value="false"
checked={showText === 2}
onClick={(e) => radioHandler(2)}
/>
{showText === 1 &&
<div>
<p>Test showing</p>
</div>}
{showText === 2 & <p></p>}
<div>
<label>Please enter any chronic conditions you have below:</label>
<input
className="chronic_medical"
type="text"
value={this.state.chronic_show}
onChange={handleInputChange}
/>
</div>
{/* Testing radio button hide/show
{/* Testing radio button hide/show */}
<label>Are you currently taking any medication?</label>
<input
className="meds_yes"
type="radio"
value="chronic"
onClick={(e) => radioHandler(1)}
/>
<input
className="meds_no"
type="radio"
value="chronic"
onClick={(e) => radioHandler(2)}
/>
<div id="meds_show">
<label>Please list any medications you take below:</label>
<input
className="meds_show"
type="text"
value={this.state.meds_show}
onChange={handleInputChange}
/>
</div>
{/* Testing radio button hide/show */}
{/* Testing radio button hide/show */}
<label>Do you, or have you had, any injuries?</label>
<input
className="injury_yes"
type="radio"
value="ture"
onChange={handleInputChange}
/>
<input
className="injnury_no"
type="radio"
value="false"
onChange={handleInputChange}
/>
<div id="injury_show">
<label>
Please enter any injuries you have had in the past below:
</label>
<input
className="injury_show"
type="text"
value={this.state.injury_show}
onChange={handleInputChange}
/>
</div>
{/* Testing radio button hide/show */}
<label>
Has a doctor ever suggested you only participate in medically
supervised exercise?
</label>
<input
className="supexr_yes"
type="radio"
value={this.state.supexr_yes}
onChange={handleInputChange}
/>
<input
className="supexr_no"
type="radio"
value={this.state.supexr_no}
onChange={handleInputChange}
/>
</div>
</div>
</form>
</div>
);
}
export default App;
And please, if you have any tips for a beginner they would be much appreciated!
The error is telling you exactly what is going wrong: this is being referenced and is undefined.
I can see you've commented out some lines, which looks as though you've moved away from using Class components to Functional components. Class components would understand this, but as you're now using a Functional component constructs like this.state.f_name are meaningless.
I don't want to re-write your code, but just want to point out that you probably want to do something like:
const [firstName, setFirstName] = useState("");
....
const handleInputChange = (event, value) => {
if(event.target.name == 'f_name'){
setFirstName(value);
}
console.log(value);
}
...
<input
name="f_name"
type="text"
value={firstName}
onChange={handleInputChange}
placeholder="Please enter your first name"
/>
You need to do something similar for all other input fields, and then tidy up the code.
I suggest you always start with something small (remove all other fields and just get one field working).
https://reactjs.org/docs/getting-started.html is an external starting place to get a better understanding of React. Happy coding.
You use this.state in your input field value but you are using hooks. You can create all your state variable using useState. Like the below:
const [inputValue, setInputValue] = useState({
f_name: '',
m_name: '',
...
})
return (
<div>
...
<input
name="f_name"
type="text"
value={inputValue.f_name}
onChange={handleInputChange}
placeholder="Please enter your first name"
/>
</div>
)

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}`}

Resources