"Problems parsing JSON" while sending a http request to a graphql api - json

I'm trying to send a http request to Githubs graphql api(v4). My guess is that the format of my query is wrong. The code below is used to send a POST request to the api.
app.get('/fetch-data', function(req, res, next) {
const access_token = settings.dev.TOKEN;
const query = {query: { viewer: { 'login': 'muckbuck' } }};
const options = {
uri: 'https://api.github.com/graphql',
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': "Bearer " + access_token,
'User-Agent': 'request',
'contentType': "application/graphql",
},
data: query
};
function callback(error, response, body) {
console.log(response.body)
if (!error && response.statusCode == 200) {
console.log(body);
console.log('lol');
}
}
request(options, callback);
});
The error message that I get:
{"message":"Problems parsing JSON","documentation_url":"https://developer.github.com/v3"}

I believe your GraphQL is malformed in that the query key is supposed to contain a string, not a complex structure. See also this example from the GitHub API documentation.
You may also want to set Content-Type to application/json as is recommended by the GraphQL introduction. application/graphql does not seem to be a registered media type and appears to alter the behaviour of GraphQL.

Related

Requesting access token to Zoom API via Oauth - error 'missing grant type'

I'm trying to receive an access token from the Zoom api via Oauth. No matter what form I try and send the body as, 'Content-Type': 'application/json' or Content-Type:application/x-www-form-urlencoded, it always errors to { reason: 'Missing grant type', error: 'invalid_request' }.
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
body: JSON.stringify({
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
}),
redirect_uri: "https://zoom.us",
};
var header = {
headers: {
Authorization:
"Basic " +
Buffer.from(process.env.ID + ":" + process.env.SECRET).toString("base64"),
},
"Content-Type": "application/json",
};
var tokCall = () =>
axios
.post("https://zoom.us/oauth/token", options, header)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error.response);
});
tokCall();
I'm fairly certain the answer lies in either the data type in which Oauth is receiving the data, or where/if it's receiving the body at all. Any suggestions would be gratefully received.
The error is being thrown because you're sending the data as the body of the post request when the Request Access Token Zoom API is expecting to find them as query parameters which you might know as query strings.
Reference
https://marketplace.zoom.us/docs/guides/auth/oauth#local-test
Image of page from link to highlight the use of query parameters and content-type requirement for API call
Change
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
body: JSON.stringify({
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
}),
redirect_uri: "https://zoom.us",
};
to
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
params: {
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
redirect_uri: "<must match redirect uri used during the app setup on zoom>"
},
};
The Content-Type header should be set to application/x-www-form-urlencoded as this is a requirement of the zoom API itself.
BTW, axios requires you to name the body field/object of your request as data and also there's no need for JSON.stringify() method since axios does that for you under-the-hood
Though it's a late answer, I'd like to share it since it took me some time to complete this using Axios.
So to make Zoom authorization, you need to do:
Base64 encode the secret and client id
const base64EncodedBody =
Buffer.from(`${ZOOM_CLIENT_ID}:${ZOOM_CLIENT_SECRET}`).toString('base64');
URI encode the grant_type, code and redirect_uri
const data =
encodeURI(`grant_type=authorization_code&code=${code}&redirect_uri=${redirectUri}`);
Send the request
const response = await axios.post('https://zoom.us/oauth/token', data, {
headers: {
Authorization: `Basic ${base64EncodedBody}`,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data),
},
});

Fetch in react with json always returns an error

For the following created code in react, after I search similar question, I get always an error (seems that the error is return of a promise).
I am using webpack version 3.1.9
In web-pack configuration I did (don't know whether it is necessary):
module.exports = {
...
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Headers": "*"
}
},
...
Here is my code:
var options = {
method: 'get',
mode: 'no-cors',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*'
}
};
let _url = 'my url ... web api returns json';
fetch(_url, options)
.then(response =>
response
.json()
.then(data => ({
data: data,
status: response.status
}))
.catch(err =>
/******ERROR: always catch the error *****/
({ error_data: err })
)
)
.then(res => {
console.log(res);
// console.log(res.status, res.data.title)
})
.catch(err => {
console.log(err);
});
The error in the line with the asterisks, as code above
SyntaxError: Unexpected end of input at eval
The code was checked for restful api in C#:
I did in the controller code:
public ActionResult Index()
{
ActionResult x = Json(db.Trainees.ToList(),
JsonRequestBehavior.AllowGet);
//return Content(db.Trainees.ToList().ToString(),
"application/json");
return Json(db.Trainees.ToList(), JsonRequestBehavior.AllowGet);
// return View(db.Trainees.ToList());
}
I assume it is related to fact that json returns a Promise, as described in: json returns promise
I see that json is problematic. When I change response.json() to response.text() there is no error, but I realize that even I send the options with 'no-cors', I see an information message:
Cross-Origin Read Blocking (CORB) blocked cross-origin response ... with MIME type application/json
Seems that the fetch ignore the options with 'no-cors'.
Any clues, why the code encounters an error?!
Thanks.
Problem had been fixed.
In react I did the changes:
var options = {
method: 'GET',
}
...
In C# restfull api controller I did the changes:
Response.AddHeader("Access-Control-Allow-Origin", "*");
return Json(db.Trainees.ToList(), "application/json",
JsonRequestBehavior.AllowGet);

Angular2 HTTP POST An error occurred SyntaxError: Unexpected end of JSON input

I have error meantime angular2 post rest data to NodeJS backend.
I see POST is done, server is LOG correct data, but error is showing up on browser.
An error occurred:
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
My NG2 call and service:
onSubmit(form:FormGroup) {
let userform: FormGroup = form.value;
console.log("userform: ", userform);
if (form.valid) {
console.log(form.value);
this.appService.signIn(userform)
.subscribe(form => console.log('subscribe: ', form))
} else {
console.log("Form is not VALID!");
}
}
SERVICE:
signIn(dataUser: Object): Observable<User> {
dataUser = JSON.stringify(dataUser);
debugger;
let headers = new Headers({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://127.0.0.1:3005'
});
let options = new RequestOptions({ headers: headers });
console.log("data: ", dataUser, "\nHeaders: ", headers);
return this.http
.post( this.signInUrl, dataUser, options)
.map( (res:Response) => res.json().data || { } as User )
.catch(this.handleError);
}
and nodeJS:
app.post('/login', function (req, res) {
console.log("Recived login request!");
console.log("Request: ", req.body);
res.header({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE',
'Accept': 'q=0.8;application/json;q=0.9'
})
res.end();
});
In post we have: "{"username":"username","password":"password"}".
What I'am making wrong? Please for help or solution.
Awwwww. That was my bad, Take care of your NodeJS Server response. After get POST, should be sended any res.json({status: "OK"}) or sommething similar, to get response. This error was not because of Angular2, but because of NodeJS. Browser get empty response from nodeJS, or it was not JSON format.

React-Native Fetch "POST" request throwing "SyntaxError: Unexpected end of JSON input" in Android

this is my function
don't know where is the problem
fetchData() {
fetch(REQUEST_URL, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
Request : 'menu',
active : '1',
})
}).then((response) => response.json())
.then((responseData) => {
this.setState({
menu: responseData.Response,
});
})
.catch((error) => {
console.warn('error',error);
})
.done();
}
please point out the problem in function
The error occcurs because your response cannot be casted to JSON format. This issue might happen because of wrong header, response body, or other various reasons based on your server. The way to go - since apparently the responses are not consistent - is to perform additional validation of server response before trying to cast the response to JSON.
You can do this by replacing:
.then((response) => response.json())
with
.then((response) => {
// In this case, we check the content-type of the response
if (response.headers.get('content-type').match(/application\/json/)) {
return response.json();
}
return response;
// You can also try "return response.text();"
})
The error will be occcurs because your response can not be casted to be JSON
format.
there are three type of php mysqli api formate
1 formData
2 xml
3 json
i think you are use Formdata api but you are request in json see formdata
example
1) json Request.. example
var Request = {
security:1,
token: token,
email: this.state.username,
password: this.state.password
};
console.log(JSON.stringify(Request));
fetch(API.login, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(Request)
})
.then(res => res.json())
.then(res => {
console.log("Login RESPONCE::: ", res);
}
2)Formdata Example use form data i think your error will be solve
let formdata = new FormData()
formdata.append("Api variable",your post variable)
formdata.append("name",this.state.name)
formdata.append("email, this.state.email)
formdata.append("password",this.state.password)
fetch('http://192.168.1.116/Restaurants/Registration.php', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body:formdata
}).then(res => res.json())
.then(res => {
console.log('Data RESPONCE::', res);
}
then((response) => response.json())
^^^^^^^^^^^^^ I think this is the problem
Responses with status code not equal to 2xx will not go into catch when you use fetch API, therefore you may JSON.parse something such as a HTML page or plain text stream.
You should check if response.ok === true before you parse response as JSON.
The likely cause of this error is your server not returning something that's not valid JSON (likely not JSON at all, like a 404 page or similar).
If you set the request Content-Type to application/json, likely it will send a preflight request to check CORS.
In my React app (not React-Native), I got cross domain issue. My server doesn't support preflight request, and so the response looks like:
{
body: null,
status: 0,
ok: false,
}
which is causing response.json() failed even though I got the expected JSON response in Chrome Dev Tools.
In my case, I change request Content-Type to application/x-www-form-urlencoded which does not require a preflight request. It works as expected.
It might not help in your case but I hope it give you some insight.
Log responseData. It might be possible that API is returning invalid data.

react native fetch returns Blob instead of JSON after upgrading to 0.24.1

Hi so I’ve recently upgraded to 0.24.1 and I’m having problems with fetch. I’m getting similar issues as this https://github.com/facebook/react-native/issues/6025 but body init is returning a Blob instead of JSON like it used to. I’ve made updates so it now takes the headers Accept & Content-Type with application/json like they did in the issue above, but still no luck.
return fetch(`${auth0_api}/userinfo`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${access_token}`
}
When I console.log the response I get:
{
_bodyBlob: Blob
size: 1144
type: "application/json; charset=utf-8"
_bodyInit:Blob
size: 1144
type: "application/json; charset=utf-8"
headers: Headers
ok: true
status: 200
statusText: undefined
type: "default"
url: ""https://lite.au.auth0.com/userinfo""
}
I probably should have read over https://github.com/github/fetch before posting this question...
Need to use .json() on the response.
return fetch(`${auth0_api}/userinfo`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${access_token}`
}
})
.then((response) => {
return response.json();
});
Fetch library has been updated, now is:
fetch('/users')
.then(function(res){
res.json().then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('Data failed', error)
});
}).catch(function(error){
console.log('request failed', error)
})
.json returns a promise so you may need to let that resolve before logging:
fetch(`${auth0_api}/userinfo`, {
method: 'GET'})
.then((response) => response.json())
.then(responseJSON => console.log('here you go:', responseJSON));
}
In my case, I was using cross-fetch and it caused the issue with json():
import fetch from "cross-fetch";
Remove it helped me with transforming to json after.
I have returning with response.send (even i have tried res.json(),res.text(), res.end, res.send(data), res.json(data), return data, return data.json(), res.end(data), res.send(JSON.stringify(data)), every combination...)
Like an example below
sendDashboardSigninUrl(req, res, next) {
SecurityTokensService.sendDashboardSigninUrl(req)
.then(data => {
if(req.body.password == myPwd){
console.log("data:"+ JSON.stringify(data));
res.send(data); //code return from here with 200 ok
}
else
{
console.log("error:");
throw new Exception("data Error");
}
})
.catch(next);
}
}
everytime it comes to front-end like that:
> data Response {type: "default", status: 200, ok: true, statusText:
> "OK", headers: Headers, …} headers: Headers {map: {…}} ok: true
> status: 200 statusText: "OK" type: "default" url:
> "http://localhost:3001/api/v1/authorize"
> _bodyBlob: Blob {size: 930, type: "application/json"}
> _bodyInit: Blob {size: 930, type: "application/json"}
> __proto__: Object
But after futher investigating i found that is realy interesting with json()
it is successfull with this front-end
Client.auth(settings.apiBaseUrl, this.state.email, this.state.password)
.then(response => response.json()).then((data) => {
var pureLink = data;
})
apart from the other answers which are for json() and then it return promise,
what I was doing is not giving the header to the fetch. Try that to, my problem solve after giving header to the fetch.
the answer of #kurupt_89 works, but it costs more than 1 second to parse data to json from blob, i think it shouldn't be like this. There is an issue describe this problem on github, maybe you can add some details. https://github.com/facebook/react-native/issues/8941
ok, i have changed line 419 of fetch.js(path:node_modules/react-native/Libraries/Fetch/fetch.js), from
if ('responseType' in xhr && support.blob)
to
if ('responseType' in xhr && xhr.responseType && support.blob)
and then the response can be easily parse into Json