I am trying to access the Scryfall API and perform the following request:
https://scryfall.com/docs/api/cards/collection
For this I have set up an Angular project that can be found on a public GitHub:
https://github.com/ProgFroz/scryfall_test_public
I have a NodeJS server running on port :7090 and the Angular frontend running on port :4200.
The request I perform looks like the following:
router.post('/scryfall/collection', (req, res) => {
const identifiers = req.body.identifiers;
console.log(identifiers);
let url = 'https://api.scryfall.com/cards/collection';
fetch(url, {
method: 'POST',
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: {
"identifiers": identifiers
}
})
.then(res => res.json()).catch((err) => console.log(err))
.then((out) => {
res.json(out);
})
.catch(err => console.log(err));
});
I would expect a JSON return, since the request was more or less successful and the documentation states that I simply need to send the header content-type JSON to retrieve a JSON body. Is there anything else I can do to get a JSON body in return?
That is the frontend snippet that calls for my backend:
this.httpClient
.post<any>('/api/posts/scryfall/collection', {
identifiers: test,
})
.subscribe((x) => {
console.log(x);
});
The identifiers look the same as in the documentation described:
{
"identifiers": [
{
"id": "683a5707-cddb-494d-9b41-51b4584ded69"
},
{
"name": "Ancient Tomb"
},
{
"set": "mrd",
"collector_number": "150"
}
]
}
The log tells me the following error:
SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at Response.json (node:internal/deps/undici/undici:6160:23)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Which is probably caused by the wrong format being returned since it is text/html instead of JSON.
Here is the whole response:
Response {
[Symbol(realm)]: null,
[Symbol(state)]: {
aborted: false,
rangeRequested: false,
timingAllowPassed: true,
requestIncludesCredentials: true,
type: 'default',
status: 400,
timingInfo: {
startTime: 3919.7346000000834,
redirectStartTime: 0,
redirectEndTime: 0,
postRedirectStartTime: 3919.7346000000834,
finalServiceWorkerStartTime: 0,
finalNetworkResponseStartTime: 0,
finalNetworkRequestStartTime: 0,
endTime: 0,
encodedBodySize: 0,
decodedBodySize: 0,
finalConnectionTimingInfo: null
},
cacheState: '',
statusText: 'Bad Request',
headersList: HeadersList {
[Symbol(headers map)]: [Map],
[Symbol(headers map sorted)]: null
},
urlList: [ [URL] ],
body: { stream: undefined }
},
[Symbol(headers)]: HeadersList {
[Symbol(headers map)]: Map(14) {
'date' => 'Wed, 13 Sep 2023 22:03:16 GMT',
'content-type' => 'text/html',
'transfer-encoding' => 'chunked',
'connection' => 'keep-alive',
'cache-control' => 'no-cache',
'vary' => 'Accept-Encoding',
'strict-transport-security' => 'max-age=31536000; includeSubDomains; preload',
'via' => '1.1 vegur',
'cf-cache-status' => 'DYNAMIC',
'report-to' => '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=CeWkpMtXv3v8DKZM6G%2BRIOAVAp7HVweoRp%2B9UcqSsK1oAaVgNAwIHcF7XO2iZPwc2Bb%2BveOCGmktNlaXdiF7zp0CTgsXPtHOXARKsYKjMWp9xDJxc4JlZh76z4cXeUd1G9WVm4x1yxLztQEBw%2Fg%3D"}],"group":"cf-nel","max_age":604800}',
'nel' => '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
'x-content-type-options' => 'nosniff',
'server' => 'cloudflare',
'cf-ray' => '8063addfef6dca89-HAM'
},
[Symbol(headers map sorted)]: null
}
}
I also used Postman to test it, which delivers the same (unavailable) results:
So the question essentially is, what exactly is wrong with my request, and how can I possible get the desired JSON body as return?
Edit:
The full response is
TypeError: The body has already been consumed.
at consumeBody (node:internal/deps/undici/undici:6072:19)
at consumeBody.next (<anonymous>)
at Response.text (node:internal/deps/undici/undici:6146:28)
at Response.json (node:internal/deps/undici/undici:6160:40)
at C:UsersjustiDocumentsVisual Studio Code Projektelotusfield_backendroutesposts.js:28:55
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
The identifiers that are put into the body of the fetch are:
[
{ id: '683a5707-cddb-494d-9b41-51b4584ded69' },
{ name: 'Ancient Tomb' },
{ set: 'mrd', collector_number: '150' }
]
Edit2: I tried to change the type of the sent identifiers to a string, which yielded the same results unfortunately.
body: {
identifiers: JSON.stringify({"identifiers": identifiers})
}
2
Answers
simplify your fetch code
Have you tried stringifying the body?
I think it does not accept the object unlike Axios