How to call GET api to send data in BODY using axios? - reactjs

I'm trying to send data in a body using the GET method.
It's working fine when i try to run using POSTMAN/cURL/Python but it's not working using AXIOS(ReactJS).
cURL:
curl -X GET \
http://127.0.0.1:8000/xyz/xyz/ayx-api/ \
-H 'Authorization: Token 980e4e673a9cfb4c99cb35313f65a446aa44faf7' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 1ee27393-b4b0-446a-b613-bd319e02e3c8' \
-H 'cache-control: no-cache' \
-d '{"dataId": 1, "date": "2018-03-01", "days": 9 }'
this curl working fine
Using Axios:
import axios from 'axios';
const baseUrl = process.env.BACKEND_SERVER_URL;
export const fetchDataObjects = async() => {
const header = {
'Content-Type': 'application/json',
'Authorization': `Token ${localStorage.token}`,
}
const data ={"dataId": 1, "date": "2018-03-01", "days": 9 }
const res= await axios.get(`${baseUrl}/ayx-api/`,{data:JSON.stringify(data)}, {headers: header})
// above line need to helop
return res.data;
}
How can i send data in body using axios in get method?
Thanks in advance.

The HTTP GET method requests shouldn't have a request body, and axios can't create a GET request with a body. It also can't create a query string for you, if you want to pass a query string, you have to do it manually, or with something like qs:
axios.get(`${baseUrl}/ayx-api/${qs.stringify(data)}`)

UPD: turns out that even manually you can't add a body to a GET request using the fetch method in the console of your browser (I've tried to do it in Google Chrome 108 and Firefox 107 they both return similar errors Request with GET/HEAD method cannot have body.). I guess it'll take some time for browsers to support it. As a workaround you can try switching to POST method on both backend (with a different path to make no collisions) and frontend.
Original answer:
You can create a GET request with body. You need to pass the body to AxiosRequestConfig (the second parameter of the axios.get method).
let body = {hit: "floor"} //can be a string or an object (refer to the docs)
axios.get(`url`, {data: body})
AxiosRequestConfig also accepts headers if you need any.
axios.get(`url`, {headers: {"Key": "keykeykey"}, data: body})
Thought the documentation says that the data is
Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'
you can actually pass the body (tested in axios 0.27) and the server should¹ receive it. And you also need to make sure that the server will accept such request since the constrain in the specification was removed almost a decade ago.
¹ - Citation from MDN's GET page:
Note: Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined. It is better to just avoid sending payloads in GET requests.
I'm using axios for NestJS e2e testing and NestJS 9.1 with ExpressJS will accept body in the GET request (yes, you can retrieve it with the #Body() decorator).

Related

BOX API by Google Apps Script - new file version upload

I've already asked the GAS community but I was advised to continue asking here...
So far I'm able to connect to BOX and get a list of files and I can download a file from BOX as well.
The whole idea is to download a file using BOX API, edit it and upload it back as a new file version using the BOX API.
I'm unable to make the last part working as it gives me error code 400.
Here is the function.
function uploadNewFileVersion() {
//767694355309 testing
var boxFileId="767694355309";
var newVerFile = DriveApp.getFileById("1sK-jcaJoD0WaAcixKtlHA85pf6t8M61v").getBlob();
var confirmAuthorization = getBoxService_().getAccessToken();
//var parent = { "id": "0" };
//"name": "apiNewVersion.xlsx",
//"parent": parent,
var payload = {
"file": newVerFile
}
var headers = {
'Authorization': 'Bearer ' + confirmAuthorization
}
var options = {
"method": "post",
"muteHttpExceptions": true,
"contentType": "multipart/form-data",
"headers": headers,
"payload": payload
}
var apiHtml = "https://upload.box.com/api/2.0/files/"+boxFileId+"/content/";
var response = UrlFetchApp.fetch(apiHtml, options);
Logger.log(response.getResponseCode());
var a = 1;
}
The boxFileId is the file on the box.
The newVerFile is the one downloaded from Box and updated. I need to make it as a new version of the Box file.
Could you please advise?
Thank you!
PEtr
I think parent and name is optional so I commented it out.
If I don't getBlob, then it returns 415 istead.
I believe your goal and situation as follows.
You want to upload a file of Google Drive using Box API with Google Apps Script.
From your question, I cannot find the official document of the method of API that you want to use. But, from the endpoint https://upload.box.com/api/2.0/files/"+boxFileId+"/content/ in your script, I guessed that you wanted to use "Upload file version".
Values of your access token and file ID are valid for using the API.
If my understanding of your question is correct, how about the following modification?
Modification points:
When I saw the official document of "Upload file version", I confirmed the following sample curl. In this case, it is considered that when the following curl command is converted to Google Apps Script, the request might work.
$ curl -i -X POST "https://upload.box.com/api/2.0/files/12345/content" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: multipart/form-data" \
-F attributes="{"name":"Contract.pdf", "parent":{"id":"11446498"}}" \
-F file=#<FILE_NAME>
From the curl command, it is found that attributes and file are sent as form and files.
And, I thought that attributes="{"name":"Contract.pdf", "parent":{"id":"11446498"}}" might should be attributes="{\"name\":\"Contract.pdf\", \"parent\":{\"id\":\"11446498\"}}".
When I saw your current script, it seems that multipart/form-data is used for contentType. In this case, boundary in the request body is required to be included. Fortunately, at UrlFetchApp, in the case of multipart/form-data, when contentType is not used, the content type is automatically included in the request header. I think that in your case, this can be used.
In your script, attributes="{"name":"Contract.pdf", "parent":{"id":"11446498"}}" is not included. But I thought that you might use it in the future script. So in this answer, this is also included.
When above points are reflected and the sample curl command on the official document is converted to Google Apps Script, the script becomes as follows.
Sample script:
Please copy and paste the following script to the script editor and set the variables, and run the function of myFunction. By this, the request same with the sample curl is requested with Google Apps Script.
function myFunction() {
const accessToken = "###"; // Please set your access token.
const fileId = "###"; // Please set your fileId.
const fileBlob = DriveApp.getFileById("1sK-jcaJoD0WaAcixKtlHA85pf6t8M61v").getBlob();
const metadata = {name: "Contract.pdf", parent: {id: "11446498"}}; // Please set your file metadata.
const params = {
method: "post",
headers: {Authorization: `Bearer ${accessToken}`},
payload: {
attributes: JSON.stringify(metadata),
file: fileBlob,
},
muteHttpExceptions: true,
};
const url = `https://upload.box.com/api/2.0/files/${fileId}/content`;
const res = UrlFetchApp.fetch(url, params);
console.log(res.getContentText());
}
I could confirm that above sample script is the same request with above sample curl.
If you don't want to use the file metadata, please remove the line of attributes: JSON.stringify(metadata), from payload.
Note:
In this case, the maximum data size ("URL Fetch POST size") of UrlFetchApp is 50 MB. Please be careful this. Ref
About the limitation of file upload of Box API, please check https://developer.box.com/guides/uploads/.
If your access token and file ID are invalid, I think that an error occurs. So please be careful this.
References:
Upload file version
Class UrlFetchApp

Axios .get request weird behaviour

I have the following get request:
return axios
.get<ArticlesResponse>(SUGGESTED_ARTICLES, {
headers: {
'Content-Type': 'application/json',
},
})
.then(onRequestSuccess)
.catch(onRequestError);
It returns me an object with the data I need, however, the data field inside the object is a string instead of an actual object. Anyone has any ideea about why? I looked it up and saw that adding that header above will fix the issue but it doesn't. Thanks in advance!
My onRequestSucces is:
export function onRequestSuccess<T = any>(response: AxiosResponse<T>) {
console.log('Request Successful!', response);
return response.data;
}
JSON.Parse() also won't fix it.
The problem may be due to the API returning a response that contains invalid JSON data, now JSON.parse would throw an error, but Axios manages the exception by setting the invalid JSON as string in the data property. Try using the Fetch API.
Since you're using a GET request (doesn't have a body) the 'Content-Type' is not being useful. This header is used to tell the server which type of content you're sending, but you're sending none. You should use it only on POST/PUT requests.
See this question for more details on this.
In order for your request to be read as JSON you have to set the header in the server. This will tell the browser you're receiving a JSON, which will then be parsed automatically by axios.

How do I retrieve data in localStorage for me to call in the axios request header?

This is my axios, how do I retrieve data in localStorage for me to call in the axios request header?
For example I want to get / post data to postman but we need a header to get the data:
import axios from 'axios'
export default axios.create({
baseURL: 'http://forexample/api',
headers: {
'timeout' : 30000,
'APP_TOKEN': 'forexampe',
'USER_TOKEN': JSON.parse(localStorage.getItem('data').data.DATA.TOKEN)
}
})
and this is a data request that I will send to Postman using the header
async componentWillMount(){
await API.post('url/api', this.state)
.then((response)=> {
let responJSON = response
})
console.log(this.state)
}
how do I retrieve data in localstorage for me to call in the axios request header?
for example I want to get / post data to postman but we need a header to get the data
and this is a data request that I will send to Postman using the header
From the docs:
The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).
So the reason that you're not getting the result you expect is you're trying to access nested data as if it were a real JS object. This seems to be an issue with how you are storing the data, rather than how you are accessing it, as the localStorage.getItem('myKey') syntax you are using is ultimately correct. What you want to do is store only the single value you want to access as its own explicit key in the localStorage object and remove all of the dot notation you have after your getItem call.

No response Data Angularjs POST / TypeScript

I'm trying to test AngularJS's post method out, but so far I have not figured out how to get it work.
Here is my code snippet.
parameter = { categoryName: '' }; <- just a dummy parameter purposely set to '' for testing purposes
this.httpService({
method: 'POST',
url: '/svc_templates/svc_fetch_category.php',<- Just echoing some JSON string.
data: parameter
}).then(function (response) {
console.log(response);
The response I'm getting is shown below.
It seems that a call to the php file is going through, but the actual data(JSON) is not returning for some reason...
Could anyone help me out?
Make sure that the server .php file is actually working using curl e.g.:
curl -X POST -d #filename.txt http://example.com/svc_templates/svc_fetch_category.php --header "Content-Type:application/json"
Where filename.txt contains the JSON data you want to send.

"Failed to parse UUID" error message on attempting to login via TrueVault api

On attempting to login via the truvault api using angular js, I am getting this error message: Failed to parse UUID. I am passing the username, password and account_id as params. I am successful using the curl command and get the success response.
The 400 error is not described in the api docs for authorization. I am not sure about if this UUID is linked to the schema_id. Would anyone (truevault guys!!) know what I am doing wrong?
I contacted truevault support on this one. Dan helped me get through it.
I was passing the username/password/account_id as url string query parameters. I had to make two changes to the code:
1. Pass the above as form data parameters
2. add the angular-post-fix.js to my project.
(Note: I am not adding the link as there are editors who will disallow the post with links to elsewhere. It has happened in the past!)
When using Node.js, the querystring API is really useful. Just pass an object to the querystring.stringify() function, and the resulting output is ready to be sent to TrueVault for login.
Additionally, I found that adding the header 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' might be necessary (which is one of the things the Angular post-fix library does).
#orthodoc is right, but is kind of tricky how to actually build the request. Lets say we are using fetch with formData params, I'd like to add an example of a successful request:
...
var formData = new FormData();
formData.append('username', username);
formData.append('password', password);
formData.append('account_id', accountId);
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
body: formData
});
...

Resources