How to handle POST request in reactjs? - reactjs

I have my ReactJS app running in http://localhost:3000/. I am receiving below form data to my React page as a POST request
<form action="http://localhost:3000/" method="post">
Employee Id: <input type="text" name="eid"><br>
Department Id: <input type="text" name="did"><br>
<input type="submit" value="Submit">
</form>
My react app should be able to handle this POST request and render the UI as below
<h1>{eid}</h1>
<h1>{did}</h1>
I am able to handle GET request using react router but struggling to handle POST request. How can I achieve this?

That is not possible if your React app is static(not server side rendered).
When you send some POST request to your react app, nginx(or other server) will not allow that kind of action(you cannot post to static files)
Even if you bypass that restriction, react script will not have any data from your POST request, because nginx will process your request and return just a html with react script to you

It will not work like php.. you need to have something like backend (node or php to pass the data) or even some site to accept the request..

First, you need maybe some theoretical view:
https://pusher.com/tutorials/consume-restful-api-react
https://www.robinwieruch.de/react-hooks-fetch-data
You should firstly save data
You save them to the state
You display them in the part where it is rendered
To download data from api (GET)- you don't do it directly in form - you only use either ComponentDidMount or UseEffect.
componentDidMount() {
fetch(ApiURL)
.then(res => res.json())
.then(res => this.setState({ planets: res }))
.catch(() => this.setState({ hasErrors: true }));
}
useEffect(async () => {
const result = await axios(
ApiURL,
);
setData(result.data);
});
To send data to api (POST)- It's complicated - you need information about client-server communication
Straight from the React docs:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})

Related

Can't upload file to YouTube using API

I keep getting a 401 error when I try to upload a file to YouTube on my application. This is the YouTube docs: https://developers.google.com/youtube/v3/docs/videos/insert
I'm using HTTP as the method for uploading. This is what YouTube suggests you to upload a video as you can do this without any meta data:
POST https://youtube.googleapis.com/youtube/v3/videos?key=[YOUR_API_KEY] HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
Content-Type: application/json
I have my application setup in a react/typescript environment, with a node/express backend.
This is how I have written the api call using axios:
export const UploadNewYouTubeVideo = (uploadFile: File, token: string) => {
return axios.post(
`https://youtube.googleapis.com/youtube/v3/videos?key=${process.env.REACT_APP_YOUTUBE_API_KEY}`,
uploadFile,
{
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/octet-stream",
},
}
);
};
I know the access token passed is correct for the YouTube channel as it successfully allows me to view/delete existing videos with that token.
For the frontend, I have a very simple useState hook that changes to the inputted file on input:
<input
id="file-upload"
name="file-upload"
type="file"
className="sr-only"
onChange={(e) =>
e?.target.files !== null &&
setUploadFile(e?.target?.files[0])
}
/>
This corresponds to a simple function that calls that api when a button called "Upload" is pushed:
const UploadVideo = () => {
if (uploadFile) {
setIsUploading(true);
return UploadNewYouTubeVideo(uploadFile, token)
.then((res) => console.log(res))
.catch((e) => console.log("Error Uploading", e.message));
}
};
This is the 401 error I keep getting (note: I hid my secret key here with XXXX):
xhr.js:210 POST https://youtube.googleapis.com/youtube/v3/videos?key=XXXXXXXXXXXXXX net::ERR_FILE_NOT_FOUND
The file is definitely being saved to state and passed to the post request:
I'd appreciate any help you guys may have.
EDIT: I'm getting a 400 error now, which I think is the mediaBodyRequired error. Which im puzzled about as I'm passing through the file for upload. Any thoughts?

Strapi POST API call issue

Why Strapi POST Call, always expecting Multi-Part request
I Don't have multi-part data in the particular content Type.
In Strapi CMS Portal, Roles & permission section, I have given access to CREATE
Post Data
Response
import React, { useState } from 'react'
export default () => {
const [description, setDescription] = useState('')
const handleSubmit = async (event) => {
event.preventDefault();
const data = await fetch('http://localhost:1337/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description
})
})
const response = await data.json();
console.log(response)
}
return (
<div className="Create">
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Description"
value={description}
onChange={(event) => {
setDescription(event.target.value)
}}
/>
<button>Submit</button>
</form>
</div>
)
}
Technology stack which I'm using in this project
Frontend: Reactjs
Backend: Strapi
When I face this issue, I may not be aware of it. What is happening in the backend(Strapi).
Thinks found after I face this issue:
When you create a new collection type in strapi CMS. Strapi will automatically create 4 Folders [config, controllers, models, services], inside the api folder, for customization purposes.
The issue, which I faced is based on the conditions which are added in the controller's folder file (post.js), then I removed that code & tried to hit that POST API call, it's working fine. Without any error.
Helpful Resource, i found in strapi documentaion:
https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#controllers
Strapi Create Customization code file in the controller file.

react submit form then redirect issue

I have a form that must serve 2 tasks after submission:
send the form data to the server
redirect to another page
I'm having difficulties making both things happen;
The first one is easily accomplished using <Form action='/blabla'>, but then I get a blank page with the returned information from the server side as text.
The second one is also easily accomplished using <Form onSubmit={handleSubmit}> with the function:
const handleSubmit = (e) => {
e.preventDefault()
fetch('/blabla', {method: 'POST'})
.then(res => res.json())
.then(data => {
history.push('/nextPage')
})
.catch(error => {
alert(error)
})
}
And it works fine, except no data is sent from the form to the server :(
So, can someone explain me please how to get both tasks above done?
Thanks in advance :)
Would be more clear if you can post the as well.
Anyway, only from the snippet I say your fetch doesnot have body field in configuration, like:
fetch('/blabla', {
method: 'POST',
headers: {
'Content-Type': 'application/json' // or 'application/x-www-form-urlencoded'
},
body: JSON.stringify(data), // adjust this according to Content-Type header
})
that might be the reason why there was no data sent to server.

CSRF Protection with Flask/WTForms and React

Has anyone successfully implemented CSRF protection for a form submitted with React (as a controlled component) to a Flask back-end (ideally with WTForms)? I've seen a lot of partial answers, and one with Django, but couldn't find anything definitive for Flask. My big issue seems to be that I don't know how to send the csrf token to my react front end, store it as a header before submitting my form, then submit my form with the correct token. Any direction would be really helpful.
So, essentially what I did is I set up a route in Flask that can receive both GET and POST requests. React sends a GET request when the component mounts, and Flask responds with the csrf token as a header (done manually). Then React stores this value in state. When the form is submitted, the csrf token from state is sent as a field, similar to the way it is sent in a pure Flask app, where it would be a hidden field. While this technically works, I am curious if this is still vulnerable to CSRF. I think the next best option is to set up CSRF protection on all endpoints, so can try that if this isn't secure.
Flask route:
#app.route('/api/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
print(request.method)
if request.method == 'GET':
return ('', {'csrf_token': form.csrf_token._value()})
elif form.validate_on_submit():
return { 'message': 'Login successful' }, 200
else:
return { 'errors': form.errors }
GET request in componentDidMount:
componentDidMount() {
axios.get('/api/login',{data: null, headers: {'Content-Type': 'application/json'}})
.then(res => {
console.log(res)
this.setState({
csrf: res.headers.csrf_token
});
})
}
POST request when form is submitted:
onSubmitLogin = e => {
e.preventDefault();
const userData = {
username: this.state.username,
password: this.state.password,
csrf_token: this.state.csrf
};
axios({
method: 'post',
url: '/api/login',
data: userData,
headers: {
'content-type': 'application/json'
}
})
.then(res => {
console.log(res);
});
}
Maybe you need flask-security-too lib
https://flask-security-too.readthedocs.io/en/stable/patterns.html#csrf

React Native Formik handleSubmit does not read return values from function

Good day!
Im having a weird experience using formik today,
I am currently working on an app that uses formik to handle forms and will do an API request inside the onSubmit() function of formik.
Every thing went well except when i use API request and wait for it's callback.
Somehow the things inside the function of onSubmit will work properly but the API callback value does not return unless i perform a UI Change in the app itself (like pressing random spots on my screen to trigger ui change).
Here is a look of my onSubmit function of formik
onSubmit={values => {
console.log("before")
let response = FunctionWithApiRequest(values);
console.log("after")
response.then((res) => {
console.log(res)
})
}}
and here is my function with api request inside
const FunctionWithApiRequest = (credentials) => {
return fetch(`${AppConfig.HOSTNAME}/v2/auth/signup`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials)
})
.then((response) => response.json())
.then((responseJson) => {
return responseJson
})
.catch((error) => {
console.log(error)
});
}
The return "responseJson" will only appear inside the onsubmit function when i perform a UI Change (like clicking random spots in my react native screen)
i was wondering what is the problem and what cause the bug.
Thank you for your response in advance.
Possibly you can do this in a separate function with await and async.For instance
async handleSubmit(){
let {credentials} = this.state
let data = await this.props.FunctionWithApiRequest(credentials)
this.setState({returnedData: data})
}
And now in your textInput/formik
onSubmit={()=>this.handleSubmit()}
I assume you have made the request api function in actions.file, not in the same file.Am i right?So what i have done is just put await before call.Which means next line will execute only when you have response returned.Comment down if you have any issue.
It was caused by the haul bundler, when you enable dugging mode.

Resources