INVALID DATA RECEIVED in flightOffers.pricing - amadeus

I'm getting an "INVALID DATA RECEIVED"/"Flight segment not found" error when making a POST request to /shopping/flight-offers/pricing. I am using data from the flightOffersSearch GET request. I'm just getting started and following the amadeus tutorial, but as far as I can tell my data and code look correct. Since I am just getting started I am running this in the test env.
Here's my data:
{"data":{"type":"flight-offers-pricing","flightOffers":[{"type":"flight-offer","id":"1","source":"GDS","instantTicketingRequired":false,"nonHomogeneous":false,"oneWay":false,"lastTicketingDate":"2022-07-27","numberOfBookableSeats":3,"itineraries":[{"duration":"PT2H27M","segments":[{"departure":{"iataCode":"LGA","terminal":"0","at":"2022-11-22T08:05:00"},"arrival":{"iataCode":"ORD","terminal":"2","at":"2022-11-22T09:32:00"},"carrierCode":"DL","number":"1189","aircraft":{"code":"223"},"operating":{"carrierCode":"DL"},"duration":"PT2H27M","id":"1","numberOfStops":0,"blacklistedInEU":false}]}],"price":{"currency":"EUR","total":"103.82","base":"83.00","fees":[{"amount":"0.00","type":"SUPPLIER"},{"amount":"0.00","type":"TICKETING"}],"grandTotal":"103.82"},"pricingOptions":{"fareType":["PUBLISHED"],"includedCheckedBagsOnly":false},"validatingAirlineCodes":["DL"],"travelerPricings":[{"travelerId":"1","fareOption":"STANDARD","travelerType":"ADULT","price":{"currency":"EUR","total":"103.82","base":"83.00"},"fareDetailsBySegment":[{"segmentId":"1","cabin":"ECONOMY","fareBasis":"XAVNA0BQ","brandedFare":"BASICECON","class":"E","includedCheckedBags":{"quantity":0}}]}]}]}}
Here's the code:
exports.confirmFlight = (req, res, next) => {
//implement the amadeus confirm flight logic
const flight = req.body.flight;
amadeus.shopping.flightOffers.pricing
.post(
JSON.stringify({
data: { type: 'flight-offers-pricing', flightOffers: [flight] },
})
)
.then((response) => {
res.send(response.result);
//console.log(response);
})
.catch((response) => res.send(response));
};
Here's the error:
"result": {
"errors": [
{
"code": 4926,
"title": "INVALID DATA RECEIVED",
"detail": "Flight segment not found",
"status": 400
}
]
},
"parsed": true

Related

issues with fetching data from rapid API, using fetch-node

I've copied the demo code off their site but it seems that I can't crack it, I've never got this error, Used double quotes and without quotes on the keys in the post options, still getting this error.
const res = await fetch("https://textanalysis-keyword-extraction-v1.p.rapidapi.com/keyword-extractor-text", {
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"x-rapidapi-key": "ksjadkasjkasjkfjhjafkakjkajkasjf", // hidden key
"x-rapidapi-host": "textanalysis-keyword-extraction-v1.p.rapidapi.com"
},
"body": {
"text": "Keyword extraction is tasked with the automatic identification of terms that best describe the subject of a document. Key phrases, key terms, key segments or just keywords are the terminology which is used for defining the terms that represent the most relevant information contained in the document. Although the terminology is different, function is the same",
"wordnum": "5"
}
})
.then(response => {
console.log(response);
console.log(response.headers);
})
.catch(err => {
console.error(err);
});
Here is the error, apparently it's something to with "[Symbol(Body internals)]" coming out as an empty object
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'https://textanalysis-keyword-extraction-v1.p.rapidapi.com/keyword-extractor-text',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] }, // error code
counter: 0
}
}
Generally, a 404 code indicates malformed request syntax, invalid request message framing, or deceptive request routing.
But everything looks good in the code snippet that you have posted above. Try this:
fetch("https://textanalysis-keyword-extraction-v1.p.rapidapi.com/keyword-extractor-text", {
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"x-rapidapi-host": "textanalysis-keyword-extraction-v1.p.rapidapi.com",
"x-rapidapi-key": ""
},
"body": {
"wordnum": "5",
"text": ""
}
})
.then(response => {
console.log(response);
})
.catch(err => {
console.error(err);
});
You can always get in touch with the support team at support#rapidapi.com

How to update the Strapi GraphQL cache, after creating new data?

How to update the cache, after creating new data?
Error message from Apollo
Store error: the application attempted to write an object with no provided id but the store already contains an id of UsersPermissionsUser:1 for this object. The selectionSet that was trying to be written is:
{
"kind": "Field",
"name": { "kind": "Name", "value": "user" },
"arguments": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [
{ "kind": "Field", "name": { "kind": "Name", "value": "username" }, "arguments": [], "directives": [] },
{ "kind": "Field", "name": { "kind": "Name", "value": "__typename" } }
]
}
}
Nativescript-vue Front-end Details
1- Watch Book Mobile app in action on YouTube: https://youtu.be/sBM-ErjXWuw
2- Watch Question video for details on YouTube: https://youtu.be/wqvrcBRQpZg
{N}-vue AddBook.vue file
apolloClient
.mutate({
// Query
mutation: mutations.CREATE_BOOK,
// Parameters
variables: {
name: this.book.name,
year: this.book.year,
},
// HOW TO UPDATE
update: (store, { data }) => {
console.log("data ::::>> ", data.createBook.book);
const bookQuery = {
query: queries.ALL_BOOKS,
};
// TypeScript detail: instead of creating an interface
// I used any type access books property without compile errors.
const bookData:any = store.readQuery(bookQuery);
console.log('bookData :>> ', bookData);
// I pin-pointed data objects
// Instead of push(createBook) I've pushed data.createBook.book
bookData.books.push(data.createBook.book);
store.writeQuery({ ...bookQuery, data: bookData })
},
})
.then((data) => {
// I can even see ID in Result
console.log("new data.data id ::::: :>> ", data.data.createBook.book.id);
this.$navigateTo(App);
})
.catch((error) => {
// Error
console.error(error);
});
What are these "Book:9": { lines in the cache?
console.log store turns out:
"Book:9": {
"id": "9",
"name": "Hadi",
"year": "255",
"__typename": "Book"
},
"$ROOT_MUTATION.createBook({\"input\":{\"data\":{\"name\":\"Hadi\",\"year\":\"255\"}}})": {
You can see all front-end GitHub repo here
Download Android apk file
Our goal is to update the cache. Add Book Method is in here:
https://github.com/kaanguru/mutate-question/blob/c199f8dcc8e80e83abdbcde4811770b766befcb5/nativescript-vue/app/components/AddBook.vue#L39
Back-end details
However, this is a frontend question a running Strapi GraphQL Server is here: https://polar-badlands-01357.herokuapp.com/admin/
GraphQL Playground
USER: admin
PASSWORD: passw123
You can see GraphQL documentation
I have so much simple Strapi GrapQL Scheme:
If you want to test it using postman or insomnia you can use;
POST GraphQL Query URL: https://polar-badlands-01357.herokuapp.com/graphql
Bearer Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNTkwODI3MzE0LCJleHAiOjE1OTM0MTkzMTR9.WIK-f4dkwVAyIlP20v1PFoflpwGmRYgRrsQiRFgGdqg
NOTE: Don't get confused with $navigateTo() it's just a custom method of nativescript-vue.
It turns out;
all code was correct accept bookData.push(createBook);
// HOW TO UPDATE
update: (store, { data }) => {
console.log("data ::::>> ", data.createBook.book);
const bookQuery = {
query: queries.ALL_BOOKS,
};
// TypeScript detail: instead of creating an interface
// I used any type access books property without compile errors.
const bookData:any = store.readQuery(bookQuery);
console.log('bookData :>> ', bookData);
// I pin-pointed data objects
// Instead of push(createBook) I've pushed data.createBook.book
bookData.books.push(data.createBook.book);
store.writeQuery({ ...bookQuery, data: bookData })
},
})
Typescipt was helping
The point is; I shouldn't trust TypeScript errors, or at least I should read more about what it really says.
Typescript just asked me to be more specific while saying: Property 'push' does not exist on type 'unknown'
TypeScript was trying to tell me I need to be more specific while calling ROOT_MUTATION data. It said: Cannot find name 'createBook' But again I ignored it.
Solution Github Branch
https://github.com/kaanguru/mutate-question/tree/solution
Sources
how to update cache
Create interface for object Typescript

Receiving [object object] from API

I tried for hours but could not extract the object value
when I execute api in postman tool I received successful message:
[
{
"Name": "Raj",
"City": "HYD",
"Initial": "SSS"
},
{
"Name": "JOHN",
"City": "HYD",
"Initial": "SSS"
},
{
"Name": "Rakesh",
"City": "HYD",
"Initial": "SSS"
}
]
But when I am trying to access same from React native but it is showing me [object object]. How to extract Name field from it?
script:
fetch('http://190.1.120.198:3538/CustomerList/api/userList', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username:'John',
password:'UZ4952!',
Organization:'NZE'
}),
}).then((response) => response.json())
.then((responseJson) => {
console.log("myMessage:"+responseJson);
})
.catch((error) => {
console.error(error);
});
It is because you are trying to print the responseJson in logs by concatenating it with a string. When you add an object to string it will always print [object object].
console.log("myMessage:"+responseJson);
Output:
myMessage:[object object]
If you want to print the exact value of your json response you can do that in these two ways:
console.log("myMessage:",responseJson);
console.log("myMessage:"+JSON.stringify(responseJson));

Lambda - headObject fails (NotFound) though objectCreated is the event

In a lambda function with the event: s3:ObjectCreated:*, calling head object on the created object returns a NotFound error.
module.exports.handler = async function(event, context, callback) {
try {
const Bucket = event.Records[0].s3.bucket.name;
const Key = event.Records[0].s3.object.key;
console.log('Bucket', Bucket);
console.log('Key', Key);
const objectHead = await s3.headObject({ Bucket, Key }).promise();
console.log('Alas! I will never discover that the objectHead is:', objectHead);
callback();
} catch(err) {
console.error('Error', err);
callback(err);
}
}
And this is the error I get:
{
NotFound: null
message: null,
code: 'NotFound',
region: null,
time: 2018-02-19T11:06:35.894Z,
requestId: 'XXXXXXXXXXX',
extendedRequestId: 'XXX.....XXX',
cfId: undefined,
statusCode: 404,
retryable: false,
retryDelay: 77.24564264820208
}
I've noticed that it says region null in the error. I suspect this is irrelevant as I'm 99% sure I'm setting it correctly:
const s3 = new AWS.S3({
region: 'us-east-1'
});
Here's the serverless.yml function declaration in case anybody's curious:
obj_head:
handler: obj_head.handler
events:
- s3:
bucket: ${self:provider.environment.BUCKET_NAME}
event: s3:ObjectCreated:*
role: arn:aws:iam::XXXXXXXXX:role/RoleWithAllS3PermissionsEver
And here is a sample for a received event:
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "2018-02-19T11:03:46.761Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:XXX"
},
"requestParameters": {
"sourceIPAddress": "X.X.X.X"
},
"responseElements": {
"x-amz-request-id": "X",
"x-amz-id-2": "X/X/X"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "14122133-28e8-4cd9-907c-af328334c56b",
"bucket": {
"name": "BUCKET_NAME",
"ownerIdentity": {
"principalId": "X"
},
"arn": "arn:aws:s3:::BUCKET_NAME"
},
"object": {
"key": "input.key",
"size": X,
"eTag": "X",
"sequencer": "X"
}
}
}
]
}
It's puzzling that the object head isn't found though the very event that triggered the function is the object's creation.
Am I doing something wrong?
Any thoughts on where to look?
The object keyname value is URL encoded, and this was causing the issue. This behaviour is documented here:
The s3 key provides information about the bucket and object involved
in the event. Note that the object keyname value is URL encoded. For
example "red flower.jpg" becomes "red+flower.jpg".
When dealing with filenames that contains Unicode characters please see this answer from Alastair McCormack:
You need to convert the URL encoded Unicode string to a bytes str
before un-urlparsing it and decoding as UTF-8.

how to return a validation property on a hapi reply like the way Joi library does it

I have my own custom validation on a property and I'd like to return a 400 response that is similar to the the JOI.validation that is returned on the other fields. This means that in addition to the error and message I'd like to return a validation property as well - so that the client can know which field to highlight.
So, instead of this
{
"statusCode": 400,
"error": "Bad Request",
"message": "phone validation error: invalid phone number"
}
I'd like to reply with this
{
"statusCode": 400,
"error": "Bad Request",
"message": "phone validation error: invalid phone number"
"validation": {
"source": "payload",
"keys": [
"phone"
]
}
How do I add the validation the the hapi reply?
I've been doing this - which has not been working
e.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(Boom.badRequest(e));
I'm also assuming that I cannot have custom validators for Joi, otherwise I would have just extended Joi. But, is there a Joi validation error type or object I can use in the reply to get Joi like object structure in my response.
BTW, my phone validation is not a simple regex and has special cases so I cannot use the Joi built in regex validator.
If you inspect the object returned by boom.badRequest('some message'), you'll get:
{ data: null,
isBoom: true,
isServer: false,
output:
{ statusCode: 400,
payload:
{ statusCode: 400,
error: 'Bad Request',
message: 'some message' },
headers: {} },
reformat: [Function] }
So you actually need to do something like
var errObj = Boom.badRequest(e);
errObj.output.payload.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(errObj);
Try this:
var errObj = Boom.badRequest(e);
errObj.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(errObj);