File upload request sent empty in React / Laravel application using api - reactjs

We are building an application that uses React framework for the frontend and Laravel framework for the backend. The problem is whenever sending a post request for '/store-image' route. The response returns with Error 500: Call to a member function storeAs() on null.
It seems that Laravel isn't reading the request.
Here is my request code:
const formDa = new FormData();
setSelectedFile(imgRef.current.files[0]);
formDa.append("file", selectedFile);
fetch("https://api.pharo-tech.xyz/store-image",{
method:'POST',
body : {
image : formDa,
},
headers : {
'Authorization': 'Bearer ' + token,
'Accept' : 'application/json',
'Content-Type' : 'multipart/form-data'
}
}).then(res=>res.json()).then(data=> console.log(data)).catch(e => console.log(e))
Here is my ImageController.php code:
public function store(Request $request) {
$request->file('image')->storeAs('profile_images', mt_rand(100, 1000000000) . ".{$request->file('image')->guessExtension()}");
}

You append formDa.append("file", selectedFile);and from API you try to get file $request->file('image'). Here your attach file stored in file not image.
You need to update your code as below.
HTML
<input type="file" onchange="onLoadImage(this)">
Script
function onLoadImage(e) {
var token = '';
var selectedFile = e.files[0];
const formDa = new FormData();
formDa.append("image", selectedFile);
fetch("https://api.pharo-tech.xyz/store-image", {
method: 'POST',
body: formDa,
headers: {
'Authorization': 'Bearer ' + token,
'Accept': 'application/json'
}
}).then(res => res.json()).then(data =>
console.log(data)).catch(e => console.log(e))
}
API
public function store(Request $request) {
$request->file('image')->storeAs('profile_images', mt_rand(100, 1000000000) . ".{$request->file('image')->guessExtension()}");
return response()->json([success: true]);
}

Related

React Native File Upload not working using Axios

I am trying to upload a file to the server and the server APIs are written using django. The file upload is working perfectly from Postman but when i try to upload from mobile app (React Native) using axios the backend is not able to read it.
Following is the Frontend Snippet:
let accessToken = await AsyncStorage.getItem('accessToken')
let formData = new FormData()
formData.append('doc_type', this.state.selectedDoc.id)
formData.append('document', this.state.selectedFiles) // <- This is the fetched file in array format . [{filname:'abc', size:12344,.....}]
formData.append('description', this.state.description.value)
formData.append('data', JSON.stringify(this.state.selectedDoc.fields))
let url = `${AppConstants.url}api/${AppConstants.apiVersion}/upload_doc`
var config = {
method: 'post',
url: url,
data: formData,
headers: {
'Authorization': `Bearer ${accessToken}`,
}
}
axios(config)
.then((resp) => {
resolve(resp)
})
.catch((err) => {
reject(err)
});
And the backend-end if else statement is as follows:
if(request.FILES.getlist("document")):
files = request.FILES.getlist("document")
....
....
....
else:
return response.JsonResponse({
'success' : False,
'message' : 'Please Upload a file'
}, status = status.HTTP_200_OK)
The above else block is executed even though the UI is sending a valid file.
Request you to please share a solution.

RESTful API Set-Cookie header is not pass with request header to back-end

I am using Spring project and AngularJS project. I tried to update the Set-Cookie header using AngularJS. But, that value is not set to the backend API.
I debug the backend service and checked the values which is requested through the request header Set-Cookie. The updated value was not exit.
myFunction: async (value1, value2, cookie) => {
try {
let header = null;
if(cookie === null){
header = {
'Content-Type': 'application/json'
}
}else{
header = {
'Content-Type': 'application/json',
'Set-Cookie' : 'YES'
}
}
const { data } = await $http({
method: 'POST',
url: RestURIs.myrequest,
headers: header,
data: {
value1: value1,
value2: value2
}
});
return data;
} catch (error) {
console.error('error on service');
return $q.reject(error);
}
}
If this is wrong way to update the header. how to do it ? please help me to identify the issue which I did ?.

React: axios post request with both params and body

Currently I have an axios post request that works fine for sending the data to Spring Boot backend. But it just wraps single list of data to json and sends it as requested body:
Example:
sendAllData(data) {
return axios.post(API_URL + "receiveData", JSON.stringify(data),
{ headers: { "Content-Type": "application/json; charset=UTF-8" },
}).then(response=> console.log("repsonse", response.status)) // is 201
}
And it receives it on backend:
#RequestMapping(path = "/receiveData", method = RequestMethod.POST)
public ResponseEntity<Void> receiveData(#RequestBody Collection<ActivePOJO> activitePOJOS) {
//DO WORK WITH activePOJOS DATA
return new ResponseEntity<>(HttpStatus.CREATED);
}
However, apart from that information, I also need to send some other info like user.id (as example), so I need my backend to receive something like this:
public ResponseEntity<Void> receiveData(#RequestBody Collection<ActivitePOJO> activePOJOS, Long userID)
But I don't know which way should I prepare axios post for something like that. Should I use params instead of body?
You can use params and body together in a request with axios. To send userID as a param:
sendAllData(data) {
return axios.post(API_URL + "receiveData", JSON.stringify(data),
{ headers: { "Content-Type": "application/json; charset=UTF-8" },
params: { userID: 1 }, //Add userID as a param
}).then(response=> console.log("repsonse", response.status)) // is 201
And receive userID in controller with #RequestParam annotation:
public ResponseEntity<Void> receiveData(#RequestBody Collection<ActivitePOJO> activePOJOS, #RequestParam("userID") Long userID){
// here you can access userID value sent from axios
}
The third parameter is config and you can pass params to it along with header as a separate key. Refer this. https://github.com/axios/axios#axiosposturl-data-config
sendAllData(data) {
return axios
.post(API_URL + 'receiveData', JSON.stringify(data), {
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
params: { userId: 2 },
})
.then((response) => console.log('response', response.status));
} // is 201

React JS and laravel passport POST method chenged to OPTIONS

When i was tried to add Authorization code in react js custom header .. POST method changed to OPTION method .
fetch('http://localhost:8000/api/user/save', {
method : 'POST',
headers: {
'Accept' : 'application/json',
'Content-Type' : 'application/x-www-form-urlencoded',
'Authorization' : 'Bearer ' + sessionStorage.getItem('token')
},
body : formBody
})
.then(response => response.json())
.then(response => {
}).catch((err) => {
alert('Something is error ! ');
});
Note : I want to use cross origin . My react app on localhost:3000 and my server localhost:8000
This is because of CORS, if your API and the front end lives on the same project you can just change http://localhost:8000/api/user/save to /api/user/save.
You can also disable CORS.

Nodejs sending external API POST request

i am trying to send a POST request from my angularjs controller to the nodejs server which should then send a full POST request to the external API and this way avoid CORS request as well as make it more secure as i'm sending relatively private data in this POST request.
My angularjs controller function for making the post request to the nodejs server looks like this and it works fine:
var noteData = {
"id":accountNumber,
"notes":[
{
"lId":707414,
"oId":1369944,
"nId":4154191,
"price":23.84
}
]
}
var req = {
method: 'POST',
url: '/note',
data: noteData
}
$http(req).then(function(data){
console.log(data);
});
Now the problem lies in my nodejs server where i just can't seem to figure out how to properly send a POST request with custom headers and pass a JSON data variable..
i've trierd using the nodejs https function since the url i need to access is an https one and not http ,i've also tried the request function with no luck.
I know that the url and data i'm sending is correct since when i plug them into Postman it returns what i expect it to return.
Here are my different attempts on nodejs server:
The data from angularjs request is parsed and retrieved correctly using body-parser
Attempt Using Request:
app.post('/buyNote', function (req, res) {
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
},
data = JSON.stringify(req.body);
};
request(options, function (error, response, body) {
if (!error) {
// Print out the response body
// console.log(body)
console.log(response.statusCode);
res.sendStatus(200);
} else {
console.log(error);
}
})
This returns status code 500 for some reason, it's sending the data wrongly and hence why the server error...
Using https
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
}
};
var data = JSON.stringify(req.body);
var req = https.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(data);
req.end();
Https attempt return a 301 status for some reasons...
Using the same data, headers and the url in Postman returns a successful response 200 with the data i need...
I don't understand how i can make a simple http request...
Please note: this is my first project working with nodejs and angular, i would know how to implement something like this in php or java easily, but this is boggling me..
So after a lot of messing around and trying different things i have finally found the solution that performs well and does exactly what i need without over complicating things:
Using the module called request-promise is what did the trick. Here's the code that i used for it:
const request = require('request-promise');
const options = {
method: 'POST',
uri: 'https://requestedAPIsource.com/api',
body: req.body,
json: true,
headers: {
'Content-Type': 'application/json',
'Authorization': 'bwejjr33333333333'
}
}
request(options).then(function (response){
res.status(200).json(response);
})
.catch(function (err) {
console.log(err);
})

Resources