I'm really new to the concept of REST and I've been trying to work with Google's Sheets, Drive, and Classroom APIs. I have been able to pull classroom roster data, but I can't for the life of me figure out how to fix this issue with a parseError and Googling for hours hasn't helped.
let init = {
method: "POST",
async: true,
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json",
},
body: {
"mimeType": "application/vnd.google-apps.spreadsheet"
},
"contentType": "application/json"
};
fetch('https://www.googleapis.com/drive/v3/files?key='+apicall, init)
.then((response) => response.json())
.then(function(data) {
console.log(data);
console.log(init);
});
The console logs are so I can view the data, this clearly isn't going to be in the final project, but every time I send the request, it throws me error 400 parseError, which Google clearly tells me is a Content-Type error, but I specified that it's JSON, so I'm a bit confused. Any help is very much appreciated!
I figured out my own answer after some tinkering around. I changed the Content-Type to application/javascript. Even though it wasn't what I was looking for, it threw an error saying to change the fetch URI. I tried, and it made a Javascript file containing nothing but [object Object]. I was confused so I changed it all back. I read up some more on JSON formatting when I came across this quote:
When you have a Javascript object, serializing JSON is very easy:
Which lead me to remember it made the empty Javascript object... ohhhh! The body information wasn't being formatted as JSON data, but rather as a Javascript array! So then I guess I should...
var bodydata = {"name": "New spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet"};
let init = {
method: "POST",
async: true,
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json",
},
body: JSON.stringify(bodydata)
...convert the Javascript data into a JSON string!
And it worked! It was very satisfying, but I figured I'd answer my own question on here for anyone else just learning REST APIs and figuring out stuff on their own like me!
Related
I am sending a post request from my flutter to a localhost api. However, the body on the server side is always empty/null. Whereas, if I send the exact same request on postman everything works fine.
String json = jsonEncode(toCheck);
Map<String,String> headers = {
"Accept": "application/json",
"content-type": "application/json",
};
var response = await http.post(
Uri.parse(userPath + 'validateUser/'),
headers: headers,
body: "{\"email\":\"david#hotmail.com\",\"username\":\"\",\"mobile_phone_number\":\"\",\"password\":\"david\"}");
print(response.statusCode);
if(response.statusCode == HttpStatus.ok){
return response.body as bool;
}
print(response.body.toString());
return false;
The status code is always 500 with the following error:
{"Message":"An error has occurred.","ExceptionMessage":"The value cannot be null"...
This error happens because the parameter "json" is null:
[HttpPost]
[Route("validateUser/", Name = "validadeUser")]
public async Task<IHttpActionResult> ValidateUser([FromBody] string json)
{
//get the username and password to validate the user
UserClient client = JsonConvert.DeserializeObject<UserClient>(json); //error happens here because the string json is null
//...
}
However, when making the same exact request on postman, everything is okay:
The host on the android emulator app is the following:
https://10.0.2.2:44304/api/user/validateUser/
PS: looks like a duplicate of Flutter POST request body is empty on server side and Flutter Dart HTTP POST request body is empty on server side but none of those solutions have worked for me, therefore I posting a new question.
It took me a while to spot the error... but in the end, I did!
Your API takes a String argument from the request body:
ValidateUser([FromBody] string json)
That may seem alright at first, since indeed, you are sending a json String as your request body. But the thing is that since you're also using these headers:
{
"Accept": "application/json",
"content-type": "application/json",
}
This bit: "content-type": "application/json" will translate your correctly formatted json String into an actual json Object! So when it reaches your API, it will no longer be a String, and so your API won't be able to receive it properly.
The solution would be to either remove the "content-type": "application/json" from your headers and keep the request body and the API function as they are, or to change the API to:
ValidateUser([FromBody] object json)
The latter is probably the most convenient, since you were going to parse it from json String to json Object anyway! 🙂
(With this API function, you COULD also remove your "content-type": "application/json" bit from the headers, and then send the request body like this:
body: jsonDecode("{\"email\":\"david#hotmail.com\",\"username\":\"\",\"mobile_phone_number\":\"\",\"password\":\"david\"}"),
Or just not jsonEncode it in the first place... Just send it as an object. This will have the same effect as sending it as a json String with "content-type": "application/json" in the header.)
Btw, as a general rule, make sure you add lots of print and log statements in your code as you develop it! It will help you spot anything that didn't go quite as you had expected, along the way. 😉 (That's how I spotted this.)
Before sending the request to the server please encode your object to complete the body property of the request. Try this:
body: json.encode({\"email\":\"david#hotmail.com\",\"username\":\"\",\"mobile_phone_number\":\"\",\"password\":\"david\"})
Cheers.
This question already has answers here:
Apps Script - UrlFetchApp.fetch {url, method: "GET"} to a gzip gets failed with code 406
(2 answers)
Closed 1 year ago.
I'm trying to login to the tableau rest API in apps script and then get all the available views under a workbook. I'm authenticating via PATs and on successful sign-in I receive a response from the API that looks like XML response.
Here's the fetch code for that:
function tableauTM() {
const options = {
method: 'post',
muteHttpExceptions: true,
contentType: 'application/json',
Accept: 'application/json',
payload: JSON.stringify(
{
credentials: {
personalAccessTokenName: 'Tableau',
personalAccessTokenSecret: '<token_secret>',
site: {
contentUrl: 'pixybi',
},
},
}
),
};
const response = UrlFetchApp.fetch(
'https://10ay.online.tableau.com/api/3.13/auth/signin', options
);
Logger.log(response)
This is the response text I receive:
<?xml version='1.0' encoding='UTF-8'?><tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_13.xsd"><credentials token="1j4LgLC1TQagsevrKPwJEw|VGo4bJwHbRQPRYxuOaeHhnsVth7nNc3e" estimatedTimeToExpiration="363:04:39"><site id="c3f66f3d-1112-4bff-a5f4-b4022e303d13" contentUrl="udacitybi"/><user id="c34bf5f6-86b8-4de6-a619-f68837bce120"/></credentials></tsResponse>
How to ensure that the response is of JSON type and if that's not possible how can
one extract the attribute values for fields like token, user, and site id?
We tried the below code but it's throwing the type error: TypeError: Cannot read property 'getChild' of null
var root = XmlService.parse(response).getRootElement().getChild('credentials').getChild('user').getAttribute('id').getValue()
You can parse XML using XML Service. Based on your error message, no root element exists, therefore you should first try hasRootElement() before calling getRootElement(). Instead you can try getDescendants() and log out its result.
Fix your options by adding Headers under the headers parameter. See the UrlFetch Docs. Basically, see headers below for what I mean. Hopefully this should enable you to receive JSON.
const options = {
method: 'post',
muteHttpExceptions: true,
contentType: 'application/json',
headers: { Accept: 'application/json' }, …
}
I am trying to post data via an API interface.
I have checked the JSON of the data with JSON formatter and tested the API post in ReqBin and they work fine but when I execute it in App Script I get the same error, seemingly ignoring the attributes I put in the options variable.
Error is
{"code":"not_acceptable","message":"I can only talk JSON. Please set 'Accept' and 'Content-Type' to 'application/json' in your http request header."}
Note: I have tried sending just the data as the payload without json.stringify'ing it as it is formatted as JSON to start with.
In all cases it executes, but comes back 406
Is there another way to add 'Accept':"application/json" into the header??
My Code
function exportNation()
{
// Make a POST request with a JSON payload.
var data = {
"person":
{
"email":"mikenizzckelisaweiner#tv.com",
"last_name":"Bozzrovowski",
"first_name":"Edwzzard",
"tags":"Imported Data,Volunteer,Sign Request"
}
};
var options = {
"method":"POST",
"Content-Type":"application/json",
'Accept':"application/json",
'muteHttpExceptions':true,
'payload':JSON.stringify(data)
};
var response = UrlFetchApp.fetch('https://xyz.xyz.com/api/v1/people?
access_token=5604da84fXXXXXXXXXXXXXXXX42da1ea',options );
}
Any help would be greatly appreciated!
Additional HTTP headers need to be sent as a headers object.
See: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#advanced-parameters
var options = {
"method":"POST",
"contentType":"application/json",
"headers": {'Accept':"application/json"},
I have a function in a React Native app that is supposed to send data to a server that I'm hosting. This function seems to be throwing errors though every time I press submit and this function is called. The function should be sending a POST request to my webserver and receive information back. It has no problem receiving information but sending is another story... The current code below is giving me an error that says "JSON Parse error: Unrecognized token '<'. But as you can see in my code below I do not even have that symbol present in the 2nd parameter of the fetch function. Occasionally, when I tweak what I have I get an error that also says 'JSON Parse error: Unexpected EOF'. I am not sure how exactly this request is I guess 'malformed'. I am pulling it straight from the docs given by Facebook. I have also tried Axiom & XMLHttpRequest and I am still seeing similar JSON errors. Anyone?
login = () => {
// check if the username is being passed off properly...
//alert(this.state.username);
fetch('MYURL', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
})
.then(function(response){ return response.json(); }) // transforms response into data that is readable for this app...
.then(function(data) {
console.log(data);
})
.done();
}
When I shoot that post request in Postman I get back header "Content-Type: text/html; charset=UTF-8". So you don't get json back at all, that's why it doesn't work. I would venture that you have to add the correct application/json header in your backend.
This is a question for anyone who has used Stripe.js. I am trying to build a payment system with express and node. I have been stuck on this problem for about a day. I just want to post a json object with {"token":"token_val","item":"item_val"}. I am so close to getting it done, but when I post the data to my payment route my json object is messed up. I am getting a json of the form {'{"token":"token_val","item":"item_val"}': ''}.
var stripeHandler = StripeCheckout.configure({
key: stripePublicKey,
locale: 'en',
token: function(token){
var cartItem = document.getElementById("Monthly").id;
var data = [{stripeTokenId: token.id, items: cartItem}];
fetch('/purchase', {
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
})
}
})
Is there something wrong with this post that's causing the issue? I can't seem to understand why I'm getting this json obj key with a blank value.
I have tried two different content types, but nothing really seems to make a difference.
The problem was that I was not using express.json(). I added app.use(express.json()) to my app.js file and this fixed everything. I hope this helps someone.