I'm trying to return a list of flights from Google's QPX Express API, howver I'm stumped on a bad request response:
{ StatusCodeError: 400 - {"error":{"errors":[{"domain":"global","reason":"badRequest","message":"Invalid inputs: received empty request."}],"code":400,"message":"Invalid inputs: received empty request."}}
Is there something wrong with how I'm approaching the structure of the request? I'm using the request-promise library
const options = {
method: 'POST',
uri: 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXXXXXXXXXXXXXX',
qs: {
"request": {
"passengers": {
"adultCount": 1 },
"slice": [{"origin": "BOS",
"destination": "LAX",
"date": "2017-03-01"
}]
}
},
json: true
}
request(options)
.then(function (response) {
console.log(response)
})
.catch(function (err) {
console.log(err)
})
I have solved the issue. The request needed to include the data in the body key with the content-type set to JSON.
This now returns data from the API as expected.
const options = {
method: 'POST',
uri: 'https://www.googleapis.com/qpxExpress/v1/trips/search?&key=XXXXXXXXXXXXXXXXXXXX',
body: {
"request": {
"passengers": {
"adultCount": "1"
},
"slice": [
{
"origin": "SFO",
"destination": "LAX",
"date": "2017-06-19"
}
],
"solutions": "1"
}
},
json: true
}
request(options)
.then(function (response) {
console.log(response.trips.tripOption[0].saleTotal)
})
.catch(function (err) {
console.log(err)
})
Check it:
const options = {
method: 'POST',
uri: 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXXXXXXXXXXXXXX',
qs: {
"request": {
"passengers": {
"adultCount": 1 },
"slice": [{"origin": "BOS",
"destination": "LAX",
"date": "2017-03-01"
}]
}
},
json: true
};
request(options)
.then(function (response) {
console.log(response);
})
.catch(function (err) {
console.log(err);
});
You forgot to end the uri string. Also please don't forget the semicolons.
Edit:
Try:
request({
url: (your url here),
method: "POST",
json: requestData
},
where requestData will be your qs.
Related
let url = "/"
fetch(url, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
})
.then(resp => resp.json())
.then(data => {
setToken(1);
})
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
I have a proxy OK: http://localhost:3001/people"
I have this json-server configurated
{
"people": [
{
"id": "1",
"name": "gustavo",
"pass": "gustavo",
"days": {
"23/02/2021": [
{
"arrive": "09:00",
"lunchstart": "12:00",
"lunchend": "13:00",
"exit": "17:00"
}
],
"24/02/2021": [
{
"arrive": "09:00",
"lunchstart": "11:30",
"lunchend": "13:00",
"exit": "17:00"
}
]
}
}
]
}
if a use "/1" it work., how to use just "/"?
I also can use INSOMNIA OR POSTMAN, it works with /people
i just changed the proxy to :
"proxy": "http://localhost:3001"
and the fetch to:
let url = "people?name=gustavo" or
let url = "people"
I took 2 days to resolve this, but thank you God haha.
Anyone with another solution ?
Im trying to use nodejs request to request data from an api called keywords everywhere, their documentation didnt have anything for nodejs, but they do have bash so what I did was I converted their bash to a nodejs request. for more context, here's their documentation :
https://api.keywordseverywhere.com/docs/#/keywords/get_keywords_data
My code seems to work because its returning a status code of 200 but the problem is that it returns a blank data:
{
"data": [],
"credits": 93735,
"time": 0
}
If the request is successful it should return something like this:
{
"data": [
{
"vol": 390,
"cpc": {
"currency": "$",
"value": "5.51"
},
"keyword": "keywords tool",
"competition": 0.33,
"trend": [
{
"month": "May",
"year": 2019,
"value": 480
}]
},
"credits": 95597600,
"time": 0.02
}
Im guessing there is something wrong with my code since I used a converter and it's not reading the body request properly. Here's my code:
var headers = {
'Authorization': 'Bearer (API-KEY-HERE)',
'Accept': 'application/x-www-form-urlencoded'
};
var options = {
url: 'https://api.keywordseverywhere.com/v1/get_keyword_data',
method: 'POST',
headers: headers,
body: 'dataSource=gkp&country=us¤cy=USD&kw[]=keywords&kw[]=keyword'
};
function callback(error, response, body) {
console.log(response.body)
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request.post(options, callback);
the problem with your code is the body, anyway this is how the code should look like:
const request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.keywordseverywhere.com/v1/get_keyword_data',
'headers': {
'Authorization': 'Bearer insertAPIKeyHere'
},
formData: {
'kw[]': 'keyword',
'country': 'us',
'currency': 'usd',
'dataSource': 'gkp'
}
};
request(options, function (error, response) {
if (error){console.log(error)};
console.log(response.body);
});
This is the response that i get from the backend:
[{
"model": "G7",
"brand": "LG",
"price": 999.99,
"image": "https://www.bell.ca/Mobility/Products/LG-G7-ThinQ?INT=MOB_mobdevpg_BTN_poplink_Mass_051016_mb_details#",
"id": 1
}, {
"model": "P20 Pro",
"brand": "Huawei",
"price": 1200,
"image": "https://www.bell.ca/Mobility/Products/Huawei-P20-Pro?INT=MOB_mobdevpg_BTN_poplink_Mass_051016_mb_details#",
"id": 2
}]
Here is the React code that i use to fetch data:
fetchData() {
fetch('http://localhost:8080/allProducts', {
'Access-Control-Allow-Origin': '*',
},)
.then(response => response.json())
.then(parsedJson => parsedJson.results)
.then(products => this.setState({
products
}))
.catch(err => console.log('error fetching data', err))
}
Using axios you can achieve it like this:
axios.get('http://localhost:8080/allProducts', {
headers: {
'Access-Control-Allow-Origin': '*',
}
})
.then(res => callback(res))
callback is a function and you can access json data from res.data
Although I think that the access control header should be set on the server and should be on response header not on request header.
If you own the server and are using express add this middleware to your backend:
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Here your Products data from backend:
[{
"model": "G7",
"brand": "LG",
"price": 999.99,
"image": "https://www.bell.ca/Mobility/Products/LG-G7-ThinQ?INT=MOB_mobdevpg_BTN_poplink_Mass_051016_mb_details#",
"id": 1
}, {
"model": "P20 Pro",
"brand": "Huawei",
"price": 1200,
"image": "https://www.bell.ca/Mobility/Products/Huawei-P20-Pro?INT=MOB_mobdevpg_BTN_poplink_Mass_051016_mb_details#",
"id": 2
}]
Then you should going each product example:
function productProcess(products) {
products.forEach(product => {
const { model, brand, price, image, id } = product;
console.log('model:', model);
//Example:
// this.setState({
// id: { model, brand, price, image },
// })
});
}
fetchData() {
fetch('http://localhost:8080/allProducts', {
'Access-Control-Allow-Origin': '*',
},)
.then(response => response.json())
.then(parsedJson => parsedJson.results)
.then(productProcess)
.catch(err => console.log('error fetching data', err))
}
I'm trying to use the Google Cloud Printing API. I previously had problems relating to the sending of my request. After some json/stringifying experimentation, I no longer get that error. Instead, my API calls are unsuccessful according to the response sent back by the Google API. Here's what I'm doing:
// Ticket used for google cloud printing
const ticket = {
"version":"1.0",
"print":{
"color":{"vendor_id":"psk:Color","type":0},
"duplex":{"type":0},
"page_orientation":{"type":0},
"copies":{"copies":1},
"dpi":{"horizontal_dpi":1200,"vertical_dpi":1200},
"media_size":{"width_microns":80000,"height_microns":58000,"is_continuous_feed":false},
"collate":{"collate":true},
"vendor_ticket_item":[
//Printer specific settings here, from the capabilities:
{"id":"psk:JobInputBin","value":"ns0000:Tray3"},
{"id":"psk:PageICMRenderingIntent","value":"psk:Photographs"},
{"id":"psk:PageMediaType","value":"ns0000:Auto"},
{"id":"psk:JobOutputBin","value":"ns0000:Auto"},
//etc.
]
}
}
request({
"method": "POST",
"content-type" : "application/json",
"url": googlePrintUrl + "submit",
"headers": {
"Authorization": "OAuth " + googleAccessToken
},
"body" : {
"printerid": "39875g133-ae7d-76hg-65af-jhe5bc682404",
"ticket": JSON.stringify(ticket),
"title": "TEST PRINT",
"content": "test msg",
"contentType": "text/plain"
},
"json": true
}, function (error, res, body){
if (error) {
console.log("There was an error with Google Cloud Print");
console.log(error);
return;
}
console.log("The server responded with:", body);
});
this request results in this response from the server:
The server responded with: { success: false,
request:
{ time: '0',
params: {},
user: 'mytest#gmail.com',
users: [ 'mytest#gmail.com' ] },
errorCode: 3,
message: 'Printer Id required for this request.' }
As you can see, the params field is empty. This is strange because when I use Postman to do the same request, this field is filled with the params I sent in the API call. Here's how I successfully did it in Postman:
Which generated the server response:
{
"success": true,
"request": {
"time": "0",
"params": {
"ticket": [
"{\"version\":\"1.0\",\"print\":{\"color\":{\"vendor_id\":\"psk:Color\",\"type\":0},\"duplex\":{\"type\":0},\"page_orientation\":{\"type\":0},\"copies\":{\"copies\":1},\"dpi\":{\"horizontal_dpi\":600,\"vertical_dpi\":600},\"media_size\":{\"width_microns\":80000,\"height_microns\":58000,\"is_continuous_feed\":false},\"collate\":{\"collate\":true},\"vendor_ticket_item\":[{\"id\":\"psk:JobInputBin\",\"value\":\"ns0000:Tray3\"},{\"id\":\"psk:PageICMRenderingIntent\",\"value\":\"psk:Photographs\"},{\"id\":\"psk:PageMediaType\",\"value\":\"ns0000:Auto\"},{\"id\":\"psk:JobOutputBin\",\"value\":\"ns0000:Auto\"}]}}"
],
"printerid": [
"39875g133-ae7d-76hg-65af-jhe5bc682404"
],
"title": [
"TEST"
],
"contentType": [
"text/plain"
],
"content": [
"**** test"
]
},
"user": "mytest#gmail.com",
"users": [
"mytest#gmail.com"
]
},
"xsrf_token": "AIp06DhAZRSLW9GlHWQLKykbpU-5fYRqcA:1531484990909",
"message": "Print job added.",
"job": {
"ticketUrl": "https://www.google.com/cloudprint/ticket?jobid\u003df11043fe-3e00-d912-11dd-c859718a5575",
"printerName": "",
"errorCode": "",
"updateTime": "1531484993830",
"title": "**** TEST",
"message": "",
"ownerId": "mytest#gmail.com",
"tags": [
"^own"
],
"uiState": {
"summary": "QUEUED",
"progress": "Delivery attempts: 1"
},
"numberOfPages": 1,
"createTime": "1531484991068",
"semanticState": {
"delivery_attempts": 1,
"state": {
"type": "QUEUED"
},
"version": "1.0"
},
"printerid": "39875g133-ae7d-76hg-65af-jhe5bc682404",
"fileUrl": "https://www.google.com/cloudprint/download?id\u003df11043fe-3e00-d912-11dd-c859718a5575",
"id": "f11043fe-3e00-d912-11dd-c859718a5575",
"rasterUrl": "https://www.google.com/cloudprint/download?id\u003df11043fe-3e00-d912-11dd-c859718a5575\u0026forcepwg\u003d1",
"contentType": "application/pdf",
"status": "QUEUED"
}
}
This is a successful printing job, and all the parameters sent by me are sent back in the response object.
So where am I going wrong in my node.js code?
Postman sends payload (printerid, content, title, etc) in formData rather than body
Underneath the "SEND" button is a button "Code" that can generate functional NodeJS (and other) snippets like
var request = require("request");
var options = { method: 'POST',
url: 'https://www.google.com/cloudprint/submit',
headers:
{ 'cache-control': 'no-cache',
Connection: 'keep-alive',
'Content-Length': '769',
'Accept-Encoding': 'gzip, deflate',
Host: 'www.google.com',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json',
Authorization: 'Bearer ya29.GlxWB5_vr8QmJw3DChvVyqpRhNJ2hsuVzwNTJoYRH6r2VVGTwDE3MLNAN8pjTB3-BDWtZeIDrCDcP5DwYGywM1vgb9VMPhoi806HrMpOpKAaKzrgiliojec6IB2Cwg',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' },
formData:
{ printerid: 'd936d368-7ea4-6f66-84fd-6d5a7a357318',
title: 'Document Title',
content: 'Hello World',
ticket: '{"version":"1.0","print":{"vendor_ticket_item":[],"color":{"type":"STANDARD_MONOCHROME"},"copies":{"copies":1}}}',
contentType: 'text/plain' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
this is my json response
{
"sessid": "some_value",
"session_name": "some_vvalue",
"token": "some_vvalue",
"user": {
"uid": "12125",
"name": "some_vvalue",
"mail": "some_vvalue",
"theme": "",
"signature": "",
"signature_format": "filtered_html",
"created": "1486476553",
"access": "1489577945",
"login": 1489585116,
"status": "1",
"timezone": "Asia/Kolkata",
"language": "",
"picture": "0",
"data": false,
"roles": {
"2": "authenticated user"
},
"rdf_mapping": {
"rdftype": ["sioc:UserAccount"],
"name": {
"predicates": ["foaf:name"]
},
"homepage": {
"predicates": ["foaf:page"],
"type": "rel"
}
}
}
}
i just want to get first three values that is session_name,session_id and token, And i am getting this value during post request,here is my code for parsing.
async onPressLogin() {
try {
loaderHandler.showLoader("Please wait!!!");
let response = await fetch(
'http://some_url/api/user/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': this.state.token,
},
body: JSON.stringify({
username: this.state.name,
password: this.state.password,
})
});
let responseText = await response.text();
let responseJson = await response.json();
if (response.status >= 200 && response.status < 300){
await AsyncStorage.setItem(SESSION_TOKEN, responseJson.token);
await AsyncStorage.setItem(SESSION_NAME,responseJson.session_name);
await AsyncStorage.setItem(SESSION_ID,responseJson.sessid);
Alert.alert('Store Token', 'Session Token'+responseJson.token)
/// Alert.alert('Server response', responseJson)
loaderHandler.hideLoader();
Actions.Documents();
}
else {
loaderHandler.hideLoader();
let error = responseText;
Alert.alert('Login', error)
}
} catch(errors) {
loaderHandler.hideLoader();
Alert.alert('Login_server', errors)
loaderHandler.hideLoader();
}
}
I am trying to store these three values in async storage for further use. Please help me tried everything but could not solve the error. Let me know if you will need any other code. Thanks
This is the error which i am getting
TypeError: expected dynamic type'string',but had type'object'