I am trying to loop through 10 league of legends matches and for each match, call another api to get the match details. So far I have a function set up like this:
function getAllMatchData(ids) {
const promises = [];
_.take(ids, 1).forEach(id => {
const promise = fetch(`https://na1.api.riotgames.com/lol/match/v4/matches/${id}`, {
headers: {"X-Riot-Token": token}})
promises.push(promise);
})
return Promise.all(promises);
}
Since the api returns 100 matches, I only take the top 10 and then create an array of promises with them. I then do this to get the results:
getAllMatchData(_.map(data['matches'], 'gameId')).then(results => {
console.log(results);
}).catch(error => {
console.log(error);
})
But the console log for the results don't have any json data in it. It prints an array of objects that look like this:
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: { body: [Gunzip], disturbed: false, error: null },
[Symbol(Response internals)]: {
url: 'https://na1.api.riotgames.com/lol/match/v4/matches/3556728982',
status: 200,
statusText: 'OK',
headers: [Headers],
counter: 0
}
}
I am not sure where the JSON data response is.
With fetch, you need to parse the response with the type of response you received.
const promise = fetch(`https://na1.api.riotgames.com/lol/match/v4/matches/${id}`, {
headers: {"X-Riot-Token": token}}).then(res => res.json())
In your case it's json. So it's as simple as calling res.json().
Related
I am trying to make an API call from my JavaScript app to an endpoint in another application.
When I call the endpoint I get the status code and the message, but I cannot access the response body in any way. I have tried different ways to get the data, but nothing seems to work for me.
In the method "someAction", I want to use the data in the response/result from the API call. I added the outputs that the single log-lines print in the code.
How can "result" be undefined while "result.status/message" are defined?
What do I have to do in order to get the data/body as JSON or String?
The API itself is tested and returns data when tested in postman.
Thanks for your help!
const request = require('request')
let callEndpoint = () => {
return new Promise((resolve, reject) => {
const url = `https://my.api.com/endpoint`
const requestOptions = {
url: url,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
'My-API-Authorization': '123456789'
},
json: true,
strictSSL: false
}
request.get(requestOptions, (err, response) => {
if(err)
{
return reject(err);
}
return resolve(response);
});
});
}
let someAction = () => {
callEndpoint()
.then(result => {
logger.logInfo(result.statusCode) // => 200
logger.logInfo(result.statusMessage) // => OK
logger.logInfo(result) // => undefined
logger.logInfo(result.toString()) // => [object Object]
logger.logInfo(result.body) // => undefined
logger.logInfo(result.data) // => undefined
JSON.parse(result.toString()) // => Unexpected token o in JSON at position 1
JSON.parse(result) // => Unexpected token o in JSON at position 1
// DO SOME STUFF WITH THE RESULT
})
}
I am trying to send a fetch request to a URL to receive some JSON, all I get back is HTTP/1.1 200 OK, when I try to console.log my request, I don't see anything in the console, I am trying to console.log the request as JSON. I am using Cloudflare's wrangler tool for the project and coding it in javascript Here is my code:
addEventListener('fetch', event => {
event.respondWith(handleRequest((event)))
})
/**
* Respond with hello worker text
* #param {Request} request
*/
async function handleRequest(request) {
return new Response('Hello worker!', {
headers: { 'content-type': 'application/json' },
})
}
const url =`URL`;
const res="";
fetch(`MYURL`)
.then((response) => {
return response.json();
})
.then((data) => {
dataRecieved=JSON.parse(data);
console.log(dataRecieved);
});
'Hello worker!' is not a valid JSON so JSON.parse(data) will not be able to work properly. You should use a code like this to return a valid JSON in the response:
return new Response('{"variants":["your-private-url/variants/1","your-private-url/variants/2"]}', {
headers: { 'content-type': 'application/json' },
status: 200
})
Now to have the result as you mentioned in your comments you need to remove the event listener and handle the fetch call this way:
fetch('your-private-url')
.then((response) => {
return response.json();
})
.then((data) => {
// 'data' here contains the object returned by your request.
// So you can log the whole object received to see its content:
console.log('Received data:\n', data);
// And you can access the fields and log them:
data.variants.forEach(variant => {
console.log('Reveived variant: ', variant);
});
});
I'm using the library isomorphic-unfetch (https://www.npmjs.com/package/isomorphic-unfetch) to get JSON data from a Rest API. This is how I make the request:
const res = await fetch(
`url`
);
To access the body I simply need to do
const response = await res.json()
But how do I access the response headers? If I log the response to my server's console this is what I see:
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
// stuff
},
[Symbol(Response internals)]: {
url: 'request url',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
What's Symbol(Response internals)? And how do I access its headers property?
To access its headers use one of the following:
const res = await fetch(url);
console.log(res.headers.get('content-type');
// or
res.headers.forEach(header => console.log(header));
https://github.github.io/fetch/#Headers
When you run into a situation like this, you'll have access to those properties on the response object, so if you want to get access to the url property you'll simply have to write response.url and you'll get what you need.
fetch({someURL}, {
method: "POST"
}).then((response) => response).then((result) => {return result.url});
I have a fetch API call that calls API back end and in return, I will get the response object with status code. What I am trying to do is base on return, I wanted to return the JSON response with status code. so that other part of the javascript can manipulate base on status code. My fetch function is as follow.
I have tried with as follow below, but it returns as a given screenshot. It gives me promise value which I didn't want to get.
export const createUser = ( posts ) => {
const apiRoute= "/api/register";
return window.fetch(`${apiRoute}`, {
"headers": headers,
method: "POST",
body: JSON.stringify(posts)
}).then(response => ({
'status' : response.status,
'data' : response.json()
}))
.catch(error => console.error('Error: ', error))
;
}
I know that it might be the duplicate from this post (Fetch api - getting json body in both then and catch blocks for separate status codes), but I do not want my data to return as a promise. Instead, I wanted to return fully constructed well form JSON data.
Something like this.
{status: 400, data: {id:1,name:Hello World}}
how can i achieve this?
"It gives me promise value"
That's right, as per the documentation.
You need to resolve that promise before resolving the outer promise.
For example
.then(response => {
return response.json().then(data => ({
status: response.status,
data
}))
})
Alternatively, use an async function
export const createUser = async ( posts ) => {
const apiRoute= "/api/register";
try {
const response = await window.fetch(apiRoute, {
headers,
method: "POST",
body: JSON.stringify(posts)
})
return {
status: response.status,
data: await response.json()
}
} catch (error) {
console.error('Error: ', error)
throw error
}
}
I'm making multiple requests with promises, getting historical pricing data for an array of stocks.
Because the responses may not come back in the same sequential order, I need a way to know which response corresponds to which request. The responses come back with no identifying information.
Here's what one response looks like:
{
history: {
day: {
date: '1996-01-02',
open: 61.4063,
close: 63.6719,
high: 63.6875,
low: 59.6406,
volume: 10507600
},
...
}
}
And here's my request:
var promises = [];
var symbols = ['MSFT', 'AAPL', 'GOOGL', 'FB', 'NVDA'];
symbols.forEach(function(symbol) {
promises.push(axios.get('https://sandbox.tradier.com/v1/markets/history', {
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + tradierACCESSTOKEN
},
params: {
symbol: symbol,
interval: 'daily',
start: '2012-01-01'
}
}));
});
axios.all(promises)
.then(function(responses) {
responses.forEach(function(response) {
var data = response.data;
// how do i know which response corresponds with the requested stock?
});
})
.catch(error => console.log(error));
axios depends on a native ES6 Promise implementation
(source)
In the case of fulfillment, response contains an array of individual responses in the same order as you added them to Promise.all. This means that response[0] will always be the response of the request for 'MSFT'.
If all of the passed-in promises fulfill, Promise.all is fulfilled with an array of the values from the passed-in promises, in the same order as defined in the iterable.
(MDN: Promise.all)
I would do this with a non-promise approuch. The http.get is just a pseude implementation:
var request = function(symbol, cb){
http.get('https://sandbox.tradier.com/v1/markets/history', {
headers: { Accept: 'application/json', Authorization: 'Bearer ' + tradierACCESSTOKEN },
params: { symbol: symbol, interval: 'daily', start: '2012-01-01' }
}, cb);
};
var done = function(err, results){
console.log(JSON.stringify(results)); // results => array same order as input
}
async.map(['MSFT', 'AAPL', 'GOOGL', 'FB', 'NVDA'], request, done);
Not sure where the callback hell is here.