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);
}
}
Related
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 }));
}
};
I want to implement Save and Edit at same page. Of course, i have alot of field input so, i can Input a few input field and save Without Rediect to another page.
What i want is get current id after POST Request so, i can use That ID to PATCH request.
Vuejs Code
<v-btn
color="primary"
v-if="isEdit === false"
small
:loading="loading"
#click="save"
>save</v-btn
>
<v-btn
color="primary"
small
:loading="loading"
#click="edit"
v-if="isEdit === true"
>edit</v-btn
>
In script
<script>
export default {
data() {
return {
form: {},
isEdit: false
}
},
save() {
this.loading = true;
axios
.post(`api/v1/partner/`, this.form)
.then((res) => {
console.log(res);
this.isEdit = true;
})
.catch((err) => {
console.log(err.response);
this.loading = false;
this.snackbar.value = true;
this.$refs.form.validate(err.response.data);
});
},
edit() {
this.isEdit = true;
axios
.patch(`api/v1/partner/${this.form.id}/`, {
})
.then((res) => {
console.log(res);
// this.$router.push(`/partner/`);
this.loading = false;
})
.catch((err) => {
console.log(err.response);
this.loading = false;
});
},
}
</script>
I'll appreciate of all ur Help. Thanks...
Assuming your API responds from the POST request with the new ID, you can simply set it to your form object
axios.post("api/v1/partner/", this.form)
.then(res => {
console.log(res)
this.isEdit = true
this.form.id = res.data.id // assuming that's the right property name
})
I am really new to react. I created a simple form with bootstrap.
I created a MySQL database. I set up an express server on port 3001 and was able to post my form data to the database successfully.
Now I am trying to send an id through the form and get the details. Can someone please guide me through this. I looked over the internet but could not find a clear example yet.
Thanks in advance
My app.js:
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.css";
import "./App.css";
import axios from "axios";
import { Form } from "react-bootstrap";
class App extends Component {
constructor(props) {
super(props);
this.state = {
id: "",
fName: "",
lName: "",
password: "",
email: "",
persons: [],
};
}
handleOnSubmit(event) {
event.preventDefault();
alert("Data Submitted Successfully");
//--------------------------------------------------------------------------------
//POST Request
// const user = {
// fName : this.state.fName,
// lName : this.state.lName,
// // email : this.state.email,
// // password : this.state.password,
// };
// axios.post(`http://localhost:3001`, { user })
// .then(res => {
// console.log(res);
// console.log(res.data);
// })
}
handleOnChange(event) {
let name = event.target.name;
let value = event.target.value;
this.setState({
[name]: value
});
}
//GET Request
handleOnSearch() {
axios.get(`http://localhost:3001`,{
params: {
id: this.state.id
}
})
.then(res => {
console.log(this.state.persons);
this.setState({ persons: res.data });
});
}
render() {
return (
<div>
<Form onSubmit={this.handleOnSubmit.bind(this)}>
<Form.Group controlId="firstName">
<Form.Label>First Name</Form.Label>
<Form.Control
type="text"
placeholder="Enter first name"
name="fName"
onChange={this.handleOnChange.bind(this)}
/>
</Form.Group>
<Form.Group controlId="lastName">
<Form.Label>Last Name</Form.Label>
<Form.Control
type="text"
placeholder="Enter last name"
name="lName"
onChange={this.handleOnChange.bind(this)}
/>
</Form.Group>
<div>
<button
variant="primary"
type="submit"
className="btn btn-primary mx-1"
>
Submit
</button>
<button variant="primary" type="reset" className="btn btn-warning">
Clear
</button>
</div>
<hr />
<br />
<div>
<Form.Group controlId="id">
<Form.Label>Id</Form.Label>
<Form.Control
type="text"
placeholder="Enter id"
name="id"
onChange={this.handleOnChange.bind(this)}
/>
</Form.Group>
<button variant="primary" className="btn btn-warning mx-1" onClick={this.handleOnSearch.bind(this)}>
Search
</button>
</div>
</Form>
</div>
);
}
}
export default App;
my server.js:
// Creating the express app
var express = require('express');
var app = express();
// Getting mysql database access
var mysql = require('mysql');
// Enabling support to the Cross-Origin Resource Sharing protocol
var cors = require('cors');
app.use(cors());
// Extracting the body of the req to expose it on command
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Writing connection details
var con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'reactmysql'
})
// Connecting to the database
con.connect((err) => {
if (err) {
console.log("There was an error connecting to the database: " + err);
}
console.log("Connected to the database");
})
// Starting listening on port 3001
app.listen(3001, () => {
console.log("I am listening on port 3001");
})
// Getting the data from the body whenever user inputs them and assigning them to backend variables
app.post('/', (req, res) => {
// var fName = req.body.user.fName
// var lName = req.body.user.lName
console.log(req);
console.log(res);
// var sql = "INSERT INTO ('firstname', 'lastname') VALUES ('" + fName + "', '" + lName + "')"
var sql = "SELECT * FROM `mytable`";
con.query(sql, (err, result) => {
if (err) {
console.log("There was an error in your query: " + err);
}
console.log("Query Executed Successfully");
console.log(result)
})
})
Add the express host in package.json of react app
"proxy": "http://localhost:3001/"
app.js
//GET Request
handleOnSearch() {
axios.get(`/${this.state.id}`
})
.then(res => {
console.log(this.state.persons);
this.setState({ persons: res.data });
});
}
server.js
app.get('/:id', (req, res) => {
const id = req.params.id;
//Rest of the code
})
edit
You can try this with your old code
In app.js add preventDefault()
handleOnSearch(event) {
event.preventDefault();
axios
.get(`http://localhost:3001`, {
params: {
id: this.state.id,
},
})
.then((res) => {
console.log(this.state.persons);
this.setState({ persons: res.data });
});
}
server.js
app.get('/', (req, res) => {
const id = req.query.id;
//Rest of the code
})
Use this with all handling.
axios.get('/:id', {
params: {
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// always executed
});
I have been able to change the activation status of companies in database on onClick event of the checkbox. Now I am not able to toggle the status of the checkbox, What I am missing Here?
I have looked on various sites, but could not find the solution.
Here is my code in which i am printing the companies.
{this.state.allCompanies.map(com => (
<tr>
<td>{com.cname} </td>
<td>
<a>
<input
type="checkbox"
name="active"
checked={com.is_active == 1 ? "true" : ""}
onClick={
(() => {
this.setState({ cked: !this.state.cked });
},
e => this.handleActivated(e, com.cid))
}
/>
</a>
</td>
</tr>
))}
Here is my function.
handleActivated(e, id) {
const comid = id;
var data = {
comid: id
};
console.log(data);
fetch("http://localhost:5000/edit/company", {
method: "POST",
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(function(response) {
if (response.status >= 400) {
throw new Error("Bad Response from server");
}
return response.json();
})
.then(function(data) {
console.log(data);
if (data === "success") {
// e.target.checked : !e.target.checked;
this.setState({ msg: "Company Edited", active: !e.target.checked });
}
})
.catch(function(err) {
console.log(err);
});
// this.setState({ });
}
You are passing two functions to the onClick and as far as I know (though I am not able to give a source for this or tell you why) react will only use the last value you give to props. This is why setting the state of cked probably did not work.
I would suggest giving it only 1 function like so:
onClick={
(e) => {
this.setState({ cked: !this.state.cked });
this.handleActivated(e, com.cid)
}
}
If you want to only execute the second one after the setState is done(since it is async), you should use the callback function of setState.
onClick={
(e) => {
this.setState({ cked: !this.state.cked }, () => {
this.handleActivated(e, com.cid)
});
}
}
I am new to the react-redux environment and have been working on a small project to get acquainted. At the moment, I am working on the login page and have successfully been able to retrieve the response whether successful or not. The problem I face is once I retrieve the response I dont know how to store and read what is in the response without a console.log.
import React from 'react';
import { connect } from 'react-redux';
import { Button, Input } from 'reactstrap';
import { IsEmpty } from '../../helpers/utils';
import { userActions } from '../../actions/user.actions';
import LoginLayoutComponent from '../layouts/loginLayout';
class LoginFormComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
Username: '',
Password: '',
submitted: false,
errors: {}
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleValidation = this.handleValidation.bind(this);
}
handleChange(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
}
handleSubmit(e) {
e.preventDefault();
let response = null;
let errors = {};
if (this.handleValidation()) {
this.setState({ submitted: true });
const { Username, Password } = this.state;
if (Username && Password) {
response = JSON.stringify(userActions.login(Username, Password));
console.log(response);
if (response != null) {
errors["Error"] = "Invalid Username or Password";
this.setState({
errors: errors
});
}
}
}
}
handleValidation() {
let isValid = true;
let errors = {};
if (this.state.submitted === true && IsEmpty(this.state.Username)) {
errors["Username"] = "Username is required";
isValid = false;
}
if (this.state.submitted === true && IsEmpty(this.state.Password)) {
errors["Password"] = "Password is required";
isValid = false;
}
this.setState({
errors: errors
});
return isValid;
}
render() {
const { Username, Password, submitted, errors } = this.state;
//var errorMessage = loginErrorMessage;
return (
<LoginLayoutComponent>
<div className="panel panel-default">
<div className="panel-heading"></div>
<div className="panel-body" autoFocus={false}>
<form method="post" name="LoginForm" onSubmit={this.handleSubmit}>
<div className='form-group row'>
<input className='form-control' type="text" placeholder="Username" name="Username" value={Username} onChange={this.handleChange} autoFocus />
{!IsEmpty(errors.Username) && <p>{errors.Username}</p>}
</div>
<div className='form-group row' >
<Input className="form-control" type="Password" placeholder="Password" name="Password" value={Password} onChange={this.handleChange} />
{!IsEmpty(errors.Password) && <p>{errors.Password}</p>}
</div>
<Button className="btn btn-warning btn-block" onClick={this.handleSubmit}>Login</Button>
</form>
{!IsEmpty(errors.Response) && <p><b>Login Failed</b>.{errors.Response}</p>}
</div>
</div>
</LoginLayoutComponent>
);
}
}
function mapStateToProps(state) {
//const { loading } = state.authentication;
return {
// loginErrorMessage: state.authentication.error && state.authentication.error.message
};
}
const LoginForm = connect(mapStateToProps)(LoginFormComponent);
export { LoginForm };
=======================================================================
Action
import { history } from '../helpers/history';
import { userService } from '../services/user.service';
import { userConstants } from '../constants/user.constants';
export const userActions = {
login,
logout
};
function login(Username, Password) {
//return dispatch => {
console.log('Action begin');
userService.login(Username, Password)
.then(
results => {
if (results.username) {
console.log('success');
history.push('/home');
return { type: userConstants.LOGIN_SUCCESS, Username };
}
}, error => {
return { error };
}
);
//};
}
====================================================================
Service
import { HandleResponse, Logout } from '../helpers/utils';
export const userService = {
login,
logout,
_setUserSession
};
function login(Username, Password) {
const requestOptions = {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8'
}),
body: JSON.stringify({
Username,
Password
})
};
const requestPath = "http://localhost:53986/api/login/postlogin";
console.log('Start Fetching');
return fetch(requestPath,requestOptions)
.then(HandleResponse)
.then(response => {
var result = response && response.results && response.results.length > 0 ? response.results[0] : null;
if (result) {
console.log('Setting session');
_setUserSession(result);
}
return {result};
}).catch(function (error) {
return Promise.reject(error);
});
}
// Login successful :: store user details
function _setUserSession(user) {
if (user.id) {
localStorage.setItem('user', JSON.stringify(user));
}
}
===========================================
IsEmpty (As requested)
export function IsEmpty(param) {
return param === null || param === undefined || param === "" || (typeof param === "object" && param.length === 0) || param === false || param === 0;
}
The expected result is to have the error displayed in the response and display it on the login form to the user.
The problem is the way you use promises in both login functions.
function login(Username, Password) {
//return dispatch => {
console.log('Action begin');
userService.login(Username, Password)
.then(
results => {
if (results.username) {
console.log('success');
history.push('/home');
return { type: userConstants.LOGIN_SUCCESS, Username };
}
}, error => {
return { error };
}
);
//};
}
When you return in this function, it returns for the then callback but not for the login function.
You could fix your functions with es6 async/await syntax (code could be wrong but the idea is here):
async function login(Username, Password) {
try {
const res = await userService.login(Username, Password);
if (results.username) {
console.log('success');
history.push('/home');
return { type: userConstants.LOGIN_SUCCESS, Username };
}
} catch (e) {
return error;
}
}
async function login(Username, Password) {
const requestOptions = {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8'
}),
body: JSON.stringify({
Username,
Password
})
};
const requestPath = "http://localhost:53986/api/login/postlogin";
console.log('Start Fetching');
const response = HandleResponse(await fetch(requestPath,requestOptions));
const result = response && response.results && response.results.length > 0 ? response.results[0] : null;
if (result) {
console.log('Setting session');
_setUserSession(result);
}
return result;
}