File upload using .fetch() in ReactJS - reactjs

I am trying to upload file using .fetch() in ReactJS as Front End and Laravel as Back End. My ReactJS code is like below
update= (event) => {
let uploadImage = event.target.file;
let form = new FormData()
form.append('uploadImage',uploadImage)
fetch('http://127.0.0.1:8000/api/addresses/upload', {
headers: {
'Authorization': 'Bearer ' + Auth.getToken(),
'Content-Type': 'multipart/form-data',
},
method: "POST",
body: form,
})
.then(response => response.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
}
My Laravel code is like below
public function fileUpload(StoreImageRequest $request)
{
$image = $request->uploadImage;
$imagename = time() . $image->getClientOriginalName();
$destinationPath = public_path('/images');
$uploadValue = $image->move($destinationPath, $imagename);
if ($uploadValue) {
return response()->json($imagename);
}
}
I am getting error like below
and
Where is the issue ?

It's because you upload the image with form field name avatar, but in your Laravel method you access it with uploadImage.
So you can try change it to the following:
$request->avatar
Please checkout the Laravel Files documentation and make sure you follow their best practices.

I had the same issue. I fixed it by removing the content type.
Please check this article
https://upmostly.com/tutorials/upload-a-file-from-a-react-component

Related

ReactJS is throwing an error when catching a response from .NET API

I am connecting my ReactJS web app to my .NET Api and I am receiving an error whenever REACTJS is receiving the response from the API.
Here is what the error is saying
The api is returning a STRING which is the JWT token. Here is the code for that particular task:
public IActionResult Login([FromBody] UserLogin userLogin)
{
var user = Authenticate(userLogin);
if (user != null)
{
var token = Generate(user);
return Ok(token);
}
else
{
return NotFound("User not found");
}
}
and here is the fetch method in REACTJS that is responsible for this task:
function getJWTToken(event) {
event.preventDefault();
const userCredentials = {
email: user_email,
password: user_password,
};
const url = Constants.API_URL_LOGIN;
fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(userCredentials),
})
.then((response) => response.json())
.then((data) => {
console.log("Success:", data);
})
.catch((error) => {
console.error("Error:", error);
});
}
I spent two hours already but I cannot figure out what to do in here since this is my first project using react and .net. Thank you for your help.
Since you are not receiving json but plain text, use response.text() to read the response
I solved my propblem now. Thank you to Stutje, he gave me the idea. Instead of using response.json() , response.text() worked.

Host images on imgbb sometimes showing error

I upload images on one of reactjs project and host on imgbb but sometimes posting is working successfully and sometimes showing error.message: "Can't get target upload source info".
What's the problem actually ?
const [coverPhoto, setCoverPhoto] = useState([]);
const onChangeCover = (data) => {
setCoverPhoto(data)
const imgAPIKey = 'c83daa0cd70c09ca51b747864c4a22e1'
const image = data[0].file
const formData = new FormData()
formData.append('image', image)
const url = `https://api.imgbb.com/1/upload?key=${imgAPIKey}`
fetch(url,
{
method: "POST",
body: formData
})
.then(res => res.json())
.then(async result => {
console.log('imgbbCover', result)
const coverPhoto = result.data.url
await fetch(`http://localhost:5000/profiles/${email}`,
{
method: 'PUT',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({ coverPhoto })
})
})
}
see the console
Finally I've find a reason not posting the images properly sometimes is actually the freemium version has some limitations, one is not hosting every time properly...
Also tried the Cloudinary free hosting and found the same issue .

React image upload not working through fetch

const submitData = (ev) => {
ev.preventDefault();
let formData = new FormData();
formData.append("topicName", topicName);
formData.append("topicMessage", topicMessage);
formData.append("pictures", pictures);
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
Accept: "application/json, text/plain, */*",
},
body: formData,
};
const sessionId = localStorage.getItem("sessionId");
let url = FormatUrl(`/api/v1/support/topic?sessionId=${sessionId}`);
fetch(url, requestOptions)
.then((res) => res.json())
.then((res) => {
ToastsStore.success(
"Ваше обращение отправлено, среднее ожидание ответа 6 часов"
);
})
.catch((error) => {
console.log(error);
});
};
Here i am sending data to upload file like this but no response getting back from Server.
Same things working in postman. Please refer to the screenshot.
Please take a look how can i fix it.
I've done some researches here.
I found this nice website: https://muffinman.io/blog/uploading-files-using-fetch-multipart-form-data/ .
Apparently you should try to remove the content-type header.
Though if it doesn't work, please inspect the network and share the request made on chrome / firefox. (F12 -> Network and then try your request)
Instead of appending data to the object like formData.append("topicName", topicName), use something like formData["topicName"] = topicName
This might solve your issue. Let me know if that helped.

Django(not rest-framework) don`t remember the sessions if a make multiple request from react app

I trying to make request from react-app(http://localhost:8082/) to django-app(not rest-framework) and after each request , request.session.items() is empty.
This is happend only when i make requests from browsers , if makes all this steps from postman the sessions middleware works good.
I think the problem is from Headers , but i don`t find it
React requests :
var qs = require('qs');
const headers = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'withCredentials':false,
'X-CSRF-TOKEN':'cwE9Ddste5nblT6ADjyi1AVhyyh4bQVirjr7CKiC3e5Fazw0YpwLmAQLFuu1X315'
}
axios.get('http://127.0.0.1:8000/users/setSession',headers)
.then(res => {
console.log(res.data);
},(error) => {
});
axios.get('http://127.0.0.1:8000/users/getSession',headers)
.then(res => {
console.log(res.data);
},(error) => {
});
Python views.py methods :
##csrf_exempt
def setSession(request):
request.session['id'] = 12312312
request.session['token'] = 'test'
return JsonResponse({'status':200},safe=False,status=202)
##is_auth
##csrf_exempt
def getSession(request):
print(request.session.items());
return JsonResponse({'status':200},safe=False)
enter image description here

Why when I'm adding onClick event to my button, CSVLINK(react-csv) is not working anymore?

I have Node.Js backend and react front-end. I have a query in the backend that returning data based on category name that I enter in an input box.
Before I add onClick event in the button it returned the results in a CSV and download it for me. After adding onClick to the button I can see that at the backend I have a successful query but at the front-end, it's not downloading my results in a csv file. I'm using the button from Semantic UI React and CSVLINK from 'react-csv' package.
Here is my code(function that I called in onClick):
handleReportButton(e){
e.preventDefault();
const value = e.target.value;
fetch(`/reportOnAnswersCategory`,{
method: 'POST',
body: JSON.stringify({
answer: value
}),
headers: {"Content-Type": "application/json"}
})
.then(data => data.json())
.then((data) => {this.setState({report : data});})
.catch(err => console.error(err));
}
This is the button(I have binded the function before, and I did 'const { report } = this.state;' before return):
<Button onClick={this.handleReportButton}>
<CSVLink data={report} >Download this report</CSVLink>
</Button>
Thanks in advance for the help
To download a file in html5 what you can do is, to set an anchor tag with download attribute,
<a href="/reportOnAnswersCategory" download="data.csv" id="btnExport" >Export data into Excel</a>
And when the user clicks the link, the download attribute appears in the save. In this case, the file will be downloaded as “data.csv”
But to pass the 'answer:value' to the api either you can change the node to accept it as a query param and change the url to href="/reportOnAnswersCategory?answer="+{value},
Or you can hide the <a> using css style,display:none and onClick of your button, do document.getElementById("btnExport").click()
Edit: When the download is using a POST request,
fetch(service_url, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
}).then(response => response.blob())
.then(response => {
var blob=response
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
window.open(base64data);
}
})
.catch(error => {
console.error(error);
});

Resources