How to send formdata with other data in MERN App? - html

I want to save a image to cloudiary from Nodejs in a Mern Application. I have data in such a way that formdata is a field.
I want to send multiple fields from frontend with formdata but whenever I am trying to assign the formdata to my object, it is getting assigned as empty object {}
Code for Component where I have 2 more fields apart from formdata or file input.
import axios from "axios";
import React, { useState } from "react";
function About({ setAboutInfo, touched = false, setInvalid }) {
const [about, setAbout] = useState({
name: "",
objective: "",
imageUrl: {},
});
const handleChange = (e) => {
var formData = new FormData();
if (e.target.name == "imageUrl") {
formData.append("imageUrl", e.target.files[0]);
setAbout({ ...about, imageUrl: formData });
} else setAbout({ ...about, [e.target.name]: e.target.value });
setAboutInfo(about);
if (!(about.name && about.objective)) {
setInvalid((prev) => ({ ...prev, about: true }));
} else {
setInvalid((prev) => ({ ...prev, about: false }));
}
};
return (
<div className="ext-container row pb-0">
<form encType="multipart/form-data">
<div className="col-md-6">
<label className="my-labels" htmlFor="">
Name
</label>
<input
value={about.name}
name="name"
type="text"
onChange={handleChange}
className={"my-inputs "}
placeholder="Enter complete name"
/>
</div>
<div className="col-md-6">
<label className="my-labels" htmlFor="">
Profile Pic
</label>
> <input
> name="imageUrl"
> type="file"
> accept="image/*"
> onChange={handleChange}
> className={"my-inputs "}
> placeholder="Choose profile pic"
> />
</div>
<div className="col-md-12">
<label className="my-labels" htmlFor="">
Objective
</label>
<textarea
name="objective"
value={about.objective}
type="text"
onChange={handleChange}
className={"my-inputs "}
rows={4}
placeholder="Enter Objective"
></textarea>
</div>
</form>
</div>
);
}
export default About;
I am sending this data to parent component from setAboutInfo method.
Parent component making request to backend
const saveData = (e) => {
e.preventDefault();
setTouched(true);
console.log({
...about,
});
// console output
**
{
name: 'Jack', objective: "Jack's objective", imageUrl: FormData}
imageUrl: FormData {}
name: "Jack"
objective: "Jack's objective"
[[Prototype]]: Object
}
**
axios
.post(
"/resume",{...about})
.then((response) => {
if (response.status == 201) {
console.log(response);
success("Data saved successfully");
}
})
.catch((e) => console.log(e));
};
In backend I am getting this as body of Post request
{ name: 'Jack', objective: "Jack's objective", imageUrl: {} }

You have to append whole body in formdata and send send form data to the api.
const saveData = (e) => {
e.preventDefault();
setTouched(true);
console.log({
...about,
});
// console output
**
{
name: 'Jack', objective: "Jack's objective", imageUrl: FormData}
imageUrl: FormData {}
name: "Jack"
objective: "Jack's objective"
[[Prototype]]: Object
}
**
let formData = new FormData();
formData.append("imageUrl", about.imageUrl);
formData.append("name", about.name);
formData.append("objective", about.objective);
axios
.post(
"/resume",formData )
.then((response) => {
if (response.status == 201) {
console.log(response);
success("Data saved successfully");
}
})
.catch((e) => console.log(e));
};
For onchange method don't save in form data.
const handleChange = (e) => {
if (e.target.name == "imageUrl") {
setAbout({ ...about, imageUrl: e.target.files[0]});
} else setAbout({ ...about, [e.target.name]: e.target.value });
setAboutInfo(about);
if (!(about.name && about.objective)) {
setInvalid((prev) => ({ ...prev, about: true }));
} else {
setInvalid((prev) => ({ ...prev, about: false }));
}
};

Related

how to set url in another input after upload file in reactjs

I am working with react with axios. i am uploading a file in react and i want to set url in another input after file upload but i am unable to get value. in console i am getting value properly but issue in input field. currently i m doing with different method.
i want uploaded file url in id="uploadRhp". please help if anybody know.
import React, { Component } from 'react';
import axios from "axios";
class TradeImportComponent extends React.Component<{},any>{
// API Endpoints
custom_file_upload_url = `https://exaample.com/api/ipo/document/upload`;
canvas: any;
// state
constructor(props) {
super(props);
this.canvas = React.createRef()
this.state = {
image_file: null,
image_preview: '',
}
}
// Image Preview Handler
handleImagePreview = (e) => {
let image_as_base64 = URL.createObjectURL(e.target.files[0])
let image_as_files = e.target.files[0];
this.setState({
image_preview: image_as_base64,
image_file: image_as_files,
})
}
// Image/File Submit Handler
handleSubmitFile = () => {
if (this.state.image_file !== null){
let formData = new FormData();
formData.append('ipoName', 'tata');
formData.append('document', this.state.image_file);
axios.post(
this.custom_file_upload_url,
formData,
{
headers: {
// "Authorization": "YOUR_API_AUTHORIZATION_KEY_SHOULD_GOES_HERE_IF_HAVE",
"Content-type": "multipart/form-data",
},
}
)
.then(res => {
console.log(`Success` + res.data.response);
var json= JSON.parse(JSON.stringify(res.data.response));
console.log(json);
console.log(json.url);
console.log(this.canvas.current.value);
this.canvas.current.value=json.url;
console.log(this.canvas.current.value);
})
.catch(err => {
console.log(err);
})
}
}
// render from here
render() {
return (
<div>
{/* image preview */}
<img src={this.state.image_preview} alt="image_preview" width="100%"/>
{this.state.url}
{/* image input field */}
<input
type="file"
onChange={this.handleImagePreview}
/>
<input type="hidden" name="logo" id="uploadlogo"/>
<input type="hidden" name="rhp" value="test#1234567" ref={this.canvas} id="uploadRhp"/>
<input type="hidden" name="financial_Pdf" id="uploadfinancial"/>
<label>Upload file</label>
<input type="submit" onClick={this.handleSubmitFile} value="Submit"/>
<ul>
</ul>
</div>
);
}
}
export default TradeImportComponent;
Use setstate in axios response store the response in state
// state
constructor(props) {
super(props);
this.canvas = React.createRef()
this.state = {
image_file: null,
image_preview: '',
uploadURL:''
}
}
handleSubmitFile = () => {
if (this.state.image_file !== null){
let formData = new FormData();
formData.append('ipoName', 'tata');
formData.append('document', this.state.image_file);
return axios.post(
this.custom_file_upload_url,
formData,
{
headers: {
// "Authorization": "YOUR_API_AUTHORIZATION_KEY_SHOULD_GOES_HERE_IF_HAVE",
"Content-type": "multipart/form-data",
},
}
)
.then(res => {
console.log(`Success` + res.data.response);
var json= JSON.parse(JSON.stringify(res.data.response));
//use setstate
setState({uploadURL:json.url)
})
.catch(err => {
console.log(err);
})
}
}
//in JSX render
<Input value={this.state.uploadUrl}/>

Cannot modify value nor placeholder of HTML forms

I'm building this app with react, when pass the actual value like
<div class="form-group">
<input
value={this.state.setupList[0]} onChange{this.handleChange}
name="date" class="form-control" placeholder={this.state.setupList[0]} />
</div>
I can see the text but no modifications allowed, that's the function I'm using for the form:
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
Please someone suggest a better approach to fix the issue
Structure of the constructor
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
setupList: [],
title: '',
description: '',
show: false,
};
}
A random function I found on internet to store input in a value
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
With that I update the db
updateData = e => {
this.setState({ loading: true})
const { currentUser } = fire.auth();
e.preventDefault();
let title = this.state.title;
let description = this.state.description;
fire.database().ref(`/master/${currentUser.uid}/setup/`)
.update({
title: this.state.title,
description: this.state.description,
})
.then(() => {
this.setState({ loading: false, show:false})
});
}
And probably the issue is here
componentDidMount = () => {
fire.database().ref(`/master/${currentUser.uid}/setup/`)
.on('value', snapshot => {
var obj = snapshot.val()
var setupList = []
var keys = []
for(let a in obj){
setupList.push(obj[a])
keys.push(a)
}
this.setState({
setupList:setupList,
keys:keys,
...
Changing value to defaultValue works as expected. Such an easy solution
<div class="form-group">
<input
defaultValue={this.state.setupList[0]} onChange{this.handleChange}
name="date" class="form-control" placeholder={this.state.setupList[0]} />
</div>

React JS Error, Cannot read property 'value' of null when processing login form

I'm attempting to build a login form using react create, which consumes the user name and password values from the following json API: https://api.myjson.com/bins/fyufr
The code:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './Login.css';
class Login extends Component {
constructor() {
super();
this.state = {
data: [],
userName: "",
password: "",
token: "",
};
} //end constructor
change = (e) => {
this.setState({
[e.target.name]: e.target.value
});
}; //end change
onSubmit = (e) =>{
e.preventDefault();
console.log(this.state);
this.setState({
userName: "",
password: "",
token: "",
});
var userName = document.getElementById('userName').value
var password = document.getElementById('password').value
for(var i=0; i < this.state.data.length; i++) {
if(userName == this.state.data[i].userName && password == this.state.data[i].password){
console.log(userName + "is logged in")
}
}
console.log("incorrect username or password")
};
componentWillMount() {
fetch('https://api.myjson.com/bins/fyufr', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
/*body: JSON.stringify({
username: '{userName}',
password: '{password}'
})*/
}) /*end fetch */
.then(results => results.json())
.then(data => this.setState({ data: data })
)
} //end life cycle
render() {
console.log(this.state.data);
return (
<form>
<input
name="userName"
placeholder="User Name"
value={this.state.userName}
onChange={e => this.change(e) }
/> <br />
<input
name="password"
type="password"
placeholder="Password"
value={this.state.password}
onChange={e => this.change(e) }
/> <br />
<input
name="token"
placeholder="Token"
value={this.state.token}
onChange={e => this.change(e) }
/> <br />
<button onClick={e => this.onSubmit(e)}>Submit</button>
</form>
);
}
}
export default Login;
My code errors out on the following line:
var userName = document.getElementById('userName').value
...the values of this.state.data outputs to the console the values in the json file, but I get the error mentioned above when the submit button is clicked. My goal is to have the login form direct the user to a landing page upon entering a matching username and password, but first, I'm trying to resolve the error am encountering. I'm new to React JS, could I please get some guidance as to what I'm doing wrong?
Simple fix. You are missing id on your form inputs. You are trying to get document.getElementById('userName').value which returns null because it dont exist.
Here's working example of your code: https://stackblitz.com/edit/react-m7iwpt
You haven't set an I'd on your input...

ReactJS, Making POST Request

I tried to create POST request in ReactJS however it does not work I keep getting
POST http://localhost:3000/ 404 (Not Found)
error,
Can someone help me please what I am doing wrong I have been trying to do it for more than 4 hours now and it is getting annoying :/
Here is my app.jsx File
import React from 'react';
import ReactDOM from 'react-dom';
import "./main.css";
import $ from 'jquery';
class ContactForm extends React.Component{
componentDidMount(){
var $form = $('.send_JSON');
var $inputName = $('.get_name');
var $inputAge = $('.get_age');
var $inputPrefix = $('.get_prefix');
var $inputEmail = $('.get_email');
var url = 'http://localhost:3000/'; //Configurable endpoint
function loadJSON(){
$.ajax({
url: url,
dataType: 'json'
}).done(function(res){
console.log(res);
console.log("DONE!")
}).fail(function(error){
console.log(error);
console.log("NOT DONE!")
});
}
function sendForm(send_name, send_age, send_prefix, send_email){
$.ajax({
url: url,
method: 'post',
dataType: 'json',
data : {
name : send_name,
age : send_age,
prefix : send_prefix,
email : send_email
}
}).done(function(res){
loadJSON();
console.log(res);
}).fail(function(error){
console.log('Error while sending Form');
readyToSubmit : '0';
});
}
$form.on('submit', function(e){
e.preventDefault();
var name = $inputName.val();
var age = $inputAge.val();
var prefix = $inputPrefix.val();
var email = $inputEmail.val();
if(name !== '' && age > 0 && email !== ''){
sendForm(name, age, prefix, email);
$inputName.val('');
$inputAge.val(0);
$inputPrefix.val('');
$inputEmail.val('');
}
});
}
state = {
name: 'Name',
age: '',
prefix: '-',
email : 'E-mail address',
nameCheck: '',
ageCheck: '',
emailCheck: '',
readyToSubmit: ''
}
handleSubmit = (e)=>{
e.preventDefault()
sendForm();
this.setState({
nameCheck: this.state.name.length <= 0 && 'Name field has to be filled.',
ageCheck: this.state.age.length <= 0 && 'Age has to be more than 0',
emailCheck: this.state.email.search('#') <= 0 && 'Email field has to be filled and consist #',
readyToSubmit: this.state.name.length > 0 && this.state.age.length > 0 && this.state.email.search('#') > 0 ? `Success ${this.state.name}` : '',
})
}
handleChange = e =>{
this.setState({
name: e.target.value,
})
}
handleChange2 = e =>{
this.setState({
age: e.target.value
})
}
handleChange3 = e =>{
this.setState({
prefix: e.target.value
})
}
handleChange4 = e =>{
this.setState({
email: e.target.value
})
}
clearForm = () => {
document.getElementById("sendForm").reset();
this.setState({
name: "",
age: "",
prefix: "Mr",
email: " "
})
}
render(){
return(
<div>
<span className="tooltip">{this.state.readyToSubmit}</span>
<form onSubmit = {this.handleSubmit} id="sendForm" className="send_JSON">
<h2>Sii Application</h2>
<img src="../img/logo.png"/>
<p>Your Name</p>
<span className="tooltip">{this.state.nameCheck}</span>
<input onChange = {this.handleChange} value ={this.state.name} className="get_name"/>
<p>Your Age</p>
<span className="tooltip">{this.state.ageCheck}</span>
<input onChange = {this.handleChange2} value ={this.state.age} type="number" min="10" max="100" className="get_age"/>
<p>Your Prefix</p>
<select onChange = {this.handleChange3} value = {this.state.prefix} className="get_prefix">
<option value = 'Mr'>Mr</option>
<option value = 'Ms'>Ms</option>
<option value = 'Mrs'>Mrs</option>
</select>
<p>Your Email</p>
<span className="tooltip">{this.state.emailCheck}</span>
<input onChange = {this.handleChange4} value ={this.state.email} type="email" className="get_email"/>
<button type="reset" onClick = {this.clearForm} name="clear">Clear</button>
<button type="submit" name="send">Send</button>
</form>
</div>
)
}
}
class App extends React.Component {
render(){
return <ContactForm/>
}
}
document.addEventListener('DOMContentLoaded', function(){
ReactDOM.render(
<App/>,
document.getElementById('app')
);
});
I dont know if there is other way to do so, I tried Axio - which didnt work for me at all.
I suggest you looking at fetch() API instead of using jQuery Ajax to make HttpRequest. It is more lightweight and will make your code looks much simpler. Here is a link to the blog from Jake Archibald and was suggested by Google to learn how to use fetch():
https://jakearchibald.com/2015/thats-so-fetch/
Also, you can find some useful examples here from Google official documents:
https://developers.google.com/web/updates/2015/03/introduction-to-fetch
I hope it helps.
Adding to the fetch() API, you can also use axios for making HttpRequest.
It is promise based HTTP client for the browser and node.js.
Documentation is simple and available here.
Here is the example for GET request:
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// Optionally the request above could also be done as
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// Want to use async/await? Add the `async` keyword to your outer
function/method.
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}

I can't fetch react form

Hi I try to make simple contact from in react, but I stuck on fetch() method.
This is my code. I have no idea what is wrong.
FrontEnd
export default class ContactForm extends React.Component<IContactFormProps, any> {
constructor(props) {
super(props);
// local state
this.state = {
tl: new TimelineMax({paused: true, delay: 1}),
name: "",
email: "",
subject: "",
message: "",
sent: false,
}
this.handleOnSubmit = this.handleOnSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleChange = this.handleChange.bind(this);
this.startAnimation = this.startAnimation.bind(this);
}
handleOnSubmit(e) {
console.log("ContactForm->handleOnSubmit(e).");
e.preventDefault();
let formData = new FormData();
formData.append(name, this.state.name);
console.log("formData: " + formData);
fetch('/contact', {
method: 'POST',
body: formData
})
.then((response) => {
console.log("response: " + response);
console.log("response.ok: " + response.ok);
return response.json();
})
.then((responseJson) => {
console.log("responseJson: " + responseJson);
})
.catch((error) => {
console.log("error from fetch: " + error);
});
}
handleClearForm(e) {
console.log("ContactForm->handleClearForm(e).");
// e.preventDefault();
}
handleChange(event) {
const target = event.target;
const name = event.target.name;
const value = event.target.value;
this.setState({
[name]: value
});
// console.log("event.target.value: " + event.target.value);
// this.setState({value: event.target.value});
}
startAnimation() {
console.log("ContactForm->startAnimation().");
}
componentDidMount() {
this.startAnimation();
}
componentWillUnmount() {
}
render() {
return (
<form className="contact-form-cnt"
onSubmit={ this.handleOnSubmit }>
<div className="top-row">
<input type="text" name="name" placeholder="Name"
className="name" ref="name"
value={this.state.name} onChange={this.handleChange}/>
<input type="text" name="email" placeholder="Em#il"
className="email" ref="email"
value={this.state.email} onChange={this.handleChange}/>
</div>
<input type="text" name="subject" placeholder="Subject"
className="subject" ref="subject"
value={this.state.subject} onChange={this.handleChange}/>
<textarea name="message" placeholder="Write Your message here."
className="message" ref="message"
value={this.state.message} onChange={this.handleChange}></textarea>
<button type="submit" name="submit"
className="submit" ref="Send"
onClick={ this.handleClearForm }>Send</button>
</form>
);
};
};
BackEnd
'use strict';
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const winston = require('winston');
const distPath = path.join(__dirname, '../dist');
const indexFileName = 'index.html';
const app = express();
const PORT = process.env.PORT || 8080;
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(express.static(distPath));
app.get('*', (req, res) => res.sendFile(path.join(distPath, indexFileName)));
app.post("/contact", (req, res) => {
try {
console.log("mail sending succes!");
}
catch ( error ) {
console.log("mail sending failure!");
}
});
app.listen(PORT, (err) => {
if (err) {
winston.error(err);
return;
}
winston.info(`Listening on port ${PORT}`);
});
URL:
http://localhost:8080/contact
and error
POST http://localhost:8080/contact 404 (Not Found)
I think it's something with url, but I'am out of ideas. Any sugestions?
try something like this:
app.post("/contact", (req, res) => {
res.json({"foo": "bar"});
});
this way you are setting an json object as result. Let me know if works.