I am using formData to send details to my backend but somehow my image path isn't being sent.
Post photo
<div className="form-group">
<label className="btn btn-block btn-success">
<input
onChange={handleChange("photo")}
ref={inputRef}
type="file"
name="photo"
accept="image"
placeholder="choose a file"
/>
</label>
</div>
this is the form i am using
Handle change and submit button
const onSubmit = (event) => {
event.preventDefault();
setValues({...values,error:"",loading:true});
createProduct(user._id,token,JSON.stringify(values))
.then(data=>{
if(data.error){
setValues({...values,error:data.error});
}else{
setValues({...values,
name:"",
description:"",
price:"",
photo:"",
stock:"",
createdProduct:data.name,
loading:false});
}
}).then(response=>{
})
.catch(err=>console.log(err));
//
};
const handleChange = name => event => {
const value=name==="photo"?event.target.files[0]:event.target.value;
formData.append(name,value)
setValues({...values,[name]:value});
//
};
And this is the api call to backend
export const createProduct=(userId,token,product)=>{
console.log(product)
return fetch(`${API}/product/create/${userId}`,{
method: "POST",
headers:{
Accept: "application/json",
Authorization: `Bearer ${token}`
},body:product
})
.then(response=>{
return response.json();
})
.catch(err=>console.log(err));
}
The api is working fine with postman , I am using formidable in backend. Some answers from stack made the path of the file have c:\fakepath and so m too confused what to do .
Thanks for help.
Related
I'm currently working in react and have a couple of forms where the onSubmit functions automatically refresh the page even if I use preventDefault(). Im passing the event into the functions as well. Could really use some guidance on why these two forms are having this issue. It hasn't been a problem elsewhere.
Here's the form. Verify is automatically passing e.
<form onSubmit={verify} className='username-password-form'>
<div className='old-password-container'>
<label className='old-password-label'>Current Password:</label>
<input
className='old-password-input'
type='password'
id={`${id}-old-password`}
value={currentPassword}
name='currentPassword'
disabled={disabled}
onChange={(e) => setCurrentPassword(e.target.value)}
/>
<Button className='submit-old' type='submit'>
Submit
</Button>
</div>
</form>
Here's the verify function called onSubmit
const verify = async (e) => {
e.preventDefault();
const user = {
username: user_name,
password: currentPassword,
};
await fetch('http://localhost:3000/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(user),
});
setDisabled(true);
};
I am trying to upload an image within my ReactJS service to my NestJS API service, through my API, but it's not working yet. This is the React code:
First the form:
<div>
<input type="file" name="urlpromo" value={urlpromo} onChange={this.changeHandler} />
</div>
<button type="submit">Submit</button>
and the functions:
changeHandler = (e) => {
this.setState({[e.target.name]: e.target.value})
}
submitBaner = (e) => {
var bodyFormData = new FormData();
bodyFormData.append('file', this.state.urlpromo);
let config = {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
}
}
e.preventDefault()
console.log(bodyFormData)
axios.post('http://localhost:3000/images/upload', bodyFormData,config)
}
The thing is that before I was sending images, only with JSON body, it was working fine, but now with form-data, I cant make it work. This is how I can upload an image with Postman:
When I try to make it work, the function console log prints this:
FormData {}__proto__: FormData
What I am doing wrong, how should I work with this form-data?
As per the docs, <input type="file"> is uncontrolled due to its read-only value.
One option is to use a ref to track the <input> element and the files property to access the File
// in your constructor
this.urlPromoRef = React.createRef()
<div>
<input type="file" ref={this.urlPromoRef} />
</div>
<button type="submit">Submit</button>
and in your submit handler
e.preventDefault()
const bodyFormData = new FormData();
bodyFormData.append('file', this.urlPromoRef.files[0]);
// no need for extra headers
axios.post('http://localhost:3000/images/upload', bodyFormData)
Another option is to simply pass the <form> itself into the FormData constructor.
<form onSubmit={this.submitBaner}>
<div>
<input type="file" name="urlpromo" /> <!-- must have a name -->
</div>
<button type="submit">Submit</button>
</form>
submitBaner = (e) => {
e.preventDefault()
const bodyFormData = new FormData(e.target); // pass in the form
axios.post('http://localhost:3000/images/upload', bodyFormData)
}
Finally, you may be able to use something like your original code but with a special check for <input type="file">. Eg
changeHandler = (e) => {
const el = e.target
this.setState({
[el.name]: el.type === "file" ? el.files[0] : el.value
})
}
After i filled the inputs and submitted the form, I want to make a POST request with React. When i use fetch outside the handleSubmit function with a static name and job value, it works. But if i use inside the handleSubmit function, it doesn't work. Why? and how can i solve this?
import React from "react";
function CreateUser() {
const handleSubmit = (e) => {
e.preventDefault();
fetch("https://reqres.in/api/users", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: `${e.target.name.value}`,
job: `${e.target.job.value}`,
}),
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name</label>
<input id="name" name="name" type="text" />
<label htmlFor="job">job</label>
<input id="job" name="job" type="text" />
<input type="submit" value="submit" />
</form>
);
}
export default CreateUser;
Can you check how to use fetch correctly. https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api you need to return response.
Your react code seems fine, not sure how are you trying to handle success and error.
Check following Sandbox which I created using your code.
https://codesandbox.io/s/adoring-breeze-7fx2g?file=/src/App.js
I'm trying to upload images to Cloudinary from my React Native app, but I'm getting the "400 Bad Request" saying the image I'm sending is ""x-cld-error": "Unsupported source URL".
ImageUpload.js
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1
})
if (!result.cancelled) {
setImageSource(result.uri);
}
}
I'm currently using the ImagePicker from expo-image-picker. I'm taking the imageSource I've obtained from above and appending it to data before sending it to Cloudinary. The result.uri shows the URL of the picture from the iOS simulator.
CreatePost.js
const uploadFile = async () => {
const data = new FormData();
data.append('file', imageSource);
data.append('upload_preset', 'test_folder')
const res = await fetch('https://api.cloudinary.com/v1_1/{my_cloudinary}/image/upload', {
method: 'POST',
body: data,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
})
const file = await res.json()
setImage(file.secure_url)
setLargeImage(file.eager[0].secure_url)
}
When I console.log res, it shows that the status is 400.
You can try using ajax. For example here:
<h1>Upload to Cloudinary with FormData</h1>
<div>
<p>
Set your cloud name in the API URL in the code: "https://api.cloudinary.com/v1_1/<strong><cloud name></strong>/image/upload" before running the example.
</p>
</div>
<form action="" method="post" enctype="multipart/form-data" onsubmit="AJAXSubmit(this); return false;">
<fieldset>
<legend>Upload example</legend>
<p>
<label for="upload_preset">Unsigned upload Preset: <input type="text" name="upload_preset">(set it here)</label>
</p>
<p>
<label >Select your photo:
<input type="file" name="file"></label>
</p>
<p>
<input type="submit" value="Submit" />
</p>
<img id="uploaded">
<div id="results"></div>
</fieldset>
</form>
enter code here https://jsfiddle.net/shirlymanor/s1hou7zr/
I want to send the fetch post request to the server from react class component. I never did fetch post. So how can I do this from that component using thunk.
class Add extends Component {
constructor(props) {
super(props);
this.state = {username: '', email:'', text:''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert (JSON.stringify(this.state))
event.preventDefault();
}
render(){
return (
<div className="addcontainer">
<div style={{display: 'flex', justifyContent: 'center'}}>
<h4>Add new task here:</h4>
</div>
<form onSubmit={this.handleSubmit}>
<div className="wrapper">
<label for="username"><b>Username</b></label>
<input type="text" value={this.state.username} onChange={e => this.setState({ username: e.target.value })} placeholder="Enter Username" name="uname" required />
<label for="email"><b>Email</b></label>
<input type="text" value={this.state.password} onChange={e => this.setState({ email: e.target.value })} placeholder="Enter Email" name="email" required />
<label for="text"><b>Text</b></label>
<input type="text" value={this.state.password} onChange={e => this.setState({ text: e.target.value })} placeholder="Enter Task" name="text" required />
<button className="login" type="submit">Add task</button>
</div>
</form>
</div>
)
}
}
I also have an example of the jquery ajax request in documentation, but it is of little help to me. Please help me to write thunk with fetch
$(document).ready(function() {
var form = new FormData();
form.append("username", "Example");
form.append("email", "example#example.com");
form.append("text", "Some text");
$.ajax({
url: 'https://uxcandy.com/~shapoval/test-task-backend/create?developer=Example',
crossDomain: true,
method: 'POST',
mimeType: "multipart/form-data",
contentType: false,
processData: false,
data: form,
dataType: "json",
success: function(data) {
console.log(data);
}
});
});
Here is thunk that works with fetch get:
const getRepos = username => async dispatch => {
try {
var url = `https://uxcandy.com/~shapoval/test-task-backend/?developer=sait&sort_field=${username}`;
const response = await fetch(url);
const responseBody = await response.json();
//console.log(responseBody.message.tasks);
dispatch(addRepos(responseBody.message.tasks));
} catch (error) {
console.error(error);
dispatch(clearRepos());
}
};
You can use second argument of fetch function to add options e.g.
fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, cors, *same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
// "Content-Type": "application/x-www-form-urlencoded",
},
redirect: "follow", // manual, *follow, error
referrer: "no-referrer", // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
For more information please refer here
other effective way to make api hit is by using axios