const access_token = ""
fetch('https://api.fitbit.com/1/user/-/profile.json', {
method: "GET",
headers: {"Authorization": "Bearer " + access_token}
})
.then(response => response.json())
//.then(json => console.log(json))
.then((out) =>
{
console.log(out.data);
document.getElementById('log').innerHTML=out.data;
})
hi, I have been trying to fetch wep API using the above js code. i have successfully fetched the data inside my debug console but now I want to fetch inside my firebase. Can someone help with this. For security purpose i removed the access token.
You code seems OK. Either your access token is not correct, or the JSON object you receive has no "data" key.
If I'm on the right page, it seems that you should use "out.user" instead of "out.data":
https://dev.fitbit.com/build/reference/web-api/user/get-profile/
make sure the out.data is string not an array or object.
Related
I am using fetch to get the API response for GET and POST requests. When an error occurs, I am able to see the status code and the text i.e, 400 Bad Request. However, there is additional information being passed that explains why the error was thrown (i.e. username did not match). I can see this additional message in the response payload via Firefox developer tool's console but I am not sure how to get it via handling the fetch response.
Here's an example request:
fetch(url, {
method: 'POST',
body: JSON.stringify({
name: name,
description: description
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + token
}
}).then(response => {
if (!response.ok) {
throw Error(response.statusText)
}
return response
})
.catch(error => {
console.log(error)
})
Any ideas? Thanks.
Thank you everyone for your suggestions.
This tutorial helped me understand what to do.
https://css-tricks.com/using-fetch/
My problem was that when there is an error, the response is not JSON, it's text. So I needed to do something like this (taken from css-tricks.com):
fetch('https://api.github.com/users/chriscoyier/repos')
.then(response => response.text())
.then(data => {
console.log(data)
});
You seem to be passing only the statusText field of the response, which corresponds to the HTTP status code (And not the response body) - for example Bad Request for HTTP response code 400.
You can read the response body using one of the methods defined on the Response object returned by the fetch API. For example, if you're expecting a JSON response body, you can have:
const onSuccess = response => {
// Do something with the response
// What you return from here will go to the next .then
}
const onFailure = response => {
// response.json() returns a promise that resolves to the JSON sent in the body
// Note that whatever is returned from here will go to the next .then
// To go to the next .catch, you can throw from here
return response.json().then(jsonResponse => console.log(jsonResponse))
}
fetch(url, {
method: 'POST',
body: JSON.stringify({
name: name,
description: description
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + token
}
}).then(response => {
if (!response.ok) {
throw response
}
return response
})
.then(onSuccess, onFailure)
.catch(err => { /* Any error thrown from the handlers will be caught here */ })
You can have a look at the Response object documentation for more details.
Based off the docs, I'd do something more along the lines of this:
const response = await fetch('http://example.com/movies.json')
const myJson = await response.json();
console.log(JSON.stringify(myJson));
Otherwise you have to do everything inside of your .then().
In regards to the additional text you are looking for, that's totally dependent on the response object, and I have no way of knowing without seeing it.
#Voxum, your answer is missing important info, like a method..and ; await is good, but remember it should be in an async function, and you dont need to use it if you "thenify" .then() as that returns the promise. from the Fetch docs, that is their basic get/HTML example. i think the OP is asking for a API call for different types of methods, which will require a more advanced setup.
The thing is with a 400 response, the server is not giving you a response message as the 404 (for example) is telling you the page is not found. Usually the only time a server will give you a response message is when you get a good (success/200). there will usually be a message at response.json() or response.text() depending on your data coming back.
after you call fetch with the url, method and any headers use
.then((response) => {console.log(response.json());}); for json and use
.then((response) => {console.log(response.text());}); for xml/text
OP has the fetch set up properly but just needs to use response.json() or response.text(). again, a 200 response can still be a "incorrect password" and this is where you'll use this. don't expect a response body on the 400/500s. good luck!
I don't have much experience with React or JavaScript. I am creating a simple application that fetches time series data from an API. The data is used to plot a line chart (React Apex Chart). All good.
The problem is that the API response size is limited to a maximum of 2,000 records, and sometimes we need more data.
The API documentation says:
The response size is limited to a maximum of 2,000 records. If more records have to be returned, the response header contains a Link header with a URI to get the next set of records:
Link: https://apiurl; rel="next"
My Fetch Code:
My code fetches the api data, sorts it and sends it to the child component(Chart).
FetchAPI(){
fetch(https://MYURLHERE?from=FROMDATE&to=TODATE)
.then(response => response.json())
.then(data => this.setState({
kWhData: data.map((kWh) => kWh._kWh),
TimeStampData: data.map((time) => time._time),
loading: false
}))
.catch(error => console.log('Fetching failed', error))
}
Link header: link →<https://MYURLHERE?from=FROMDATE&limit=2000&to=TODATE>; rel="next">
I know the solution may be some kind of pagination but I do not fully understand this concept. I have searched for similar problems with no luck.
Hope someone could provide me with a helping hand, tips or code.
I don't know what API you're using, but it sounds like all you need to do is get the URL to the next set of results from the headers and then make a request to that.
Before you return response.json(), you can access the headers with response.headers.get(). So you can do something like let nextPage = response.headers.get('Link') to get that full Link header as a string. Then you can split it at the semicolon and use the first part as the URL for the next paginated request.
If I've understood the question correctly, I would add a variable to your FetchApi function, so that it can query either your initial API URL, or the URL for a subsequent page:
FetchAPI(requestURL){
// Fetch function here
}
The idea is that this function can then call itself iteratively, with the url of the ‘next’ page of results passed as a parameter for each call, until the response indicates all the data has been retrieved.
So your initial call would be FetchAPI('https://MYURLHERE?from=FROMDATE&to=TODATE').
You can then add a line to call this function again if the rate limit is reached. E.g:
FetchAPI(requestURL){
fetch(requestURL)
.then(response => {
if(response.dataLimit == true){ // Or however this is expressed
// Concat new data with any already retrieved
this.FetchAPI(nextPageUrl) // Get the URL of the next page and call FetchAPI again with this e.g https://MYURLHERE?from=FROMDATE&limit=2000&to=TODATE
} else {
// Otherwise stop and do something else now that you have a complete set of data
}
})
}
Worth saying that this is untested code, but hopefully enough to get the principle across.
Also if the API has a request rate limit e.g. 1 second, you could add a delay before the function calls itself again, though obviously this will impact the overall time to retrieve all of the data.
Thank you all. I got it to work with a mix of both answers.
I do not know if this is a good way to do it or the "right" approach. Maybe you guys could give me some feedback?
The setTimeout was just for testing, but I think I need to have minimum 1000?
The credentials/header is necessary to get the API.
FetchAPI(requestURL) {
fetch(requestURL, {
credentials: 'include',
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"x-xsrf-token": this.myXRSFToken,
"origin": `${window.location.protocol}//${window.location.host}`
}
})
.then(response => {
let Responseheader = response.headers.get('Link')
response.json()
.then(data => this.setState({
TestData: this.state.TestData.concat(data)
}))
if (Responseheader){
let nextPageUrl = Responseheader.match(/\bhttps?:\/\/\S+Z/gi)
setTimeout(() => {
this.FetchAPI(nextPageUrl)
}, 2000);
} else {
console.log('Done fetching API')
this.setState({
loading: false
})
return
}
})
.catch(error => console.log('Fetching failed', error))
}
I am trying to make a site where I fetch my favorite podcasts from Podbean API.
I have worked with fetch before, but those API's were much easier to setup and there was no auth part. So that's what I am struggling with.
So this is basically what I have used before :
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
From what I understand looking through various other threads :
I need to send get request with my client_id and client_secret to the get the access_token
From there on with access_token I get access and therefore can fetch date from the podcasts object.
I would appreciate any kind of guidance how to handle the auth part and obviously let me know if some of my thought processes are completely wrong.
Thanks in advance!
Ok, so I know the question is over 2 years old but I will still share my solution as I have struggled A LOT to understand how to use this API. This solution is only applicable if you are the owner of the podcast (or at least have access to the dev account).
The thing with the API is if you do not want to use auth2 (which I am still not sure how it works exactly with podbean), you have to fecth the data with a POST method not a GET and provide parameters (body and headers) and use HTTP basic authentication scheme. Their documentation is only in php but with some research you get what they are doing, the section applicable to this solution can be found here.
Here is the code:
const fetch = require("node-fetch");
const btoa = require('btoa');
const client_id = 'Enter your client id';
const client_secret = 'Enter your client secret';
const uri = 'https://api.podbean.com/v1/oauth/token';
// Base 64 encode client_id and client_secret to use basic authentication scheme
const auth = "Basic " + btoa(client_id + ':' + client_secret);
// Set POST request params
const options = {
method: 'POST',
body: 'grant_type=client_credentials',
headers : {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": auth
}
}
// Fetch
fetch(uri, options)
.then(res => res.json())
.then(data => console.log(data))
I hope this helps anyone who would try to use this API with javascript in the future.
I am using Nodejs, Express, MySQL, body-parser and EJS.
What I am trying to do is, when someone press on a button, it sends a PUT request which will update the counter by 1, I am trying to send the ID of the pressed button so it can be incremented by 1.
app.put("/toolong", function(req,res){
console.log(res.status(200).json({voteNum: 5}))
}
)
The Fetch:
function upvote(click){
// when the upvote button is clicked
let idOfClicked;
console.log(event.target.attributes[1].value)
idOfClicked = event.target.attributes[1].value
fetch(`/toolong`, { method: 'PUT', data: {id:9} })
.then(res => res.json())
.then(jsonRes => {
console.log(jsonRes.voteNum) // gives 5
})
}
I am trying to send the variable idOfClicked from the Fetch to my app.put so I can do a SQL query which will use that variable.
I assume you are able to do it, the "data" key in the fetch is something I tried from seeing some examples but I wasn't able to send it through
It's a body key instead of data.
I fixed it, the problem was I didn't have "headers: new Headers({ "Content-Type": "application/json" })" in my app.put, I placed it after my "body"
I'm trying to retrieve json from a domain which don't allow CORS and I don't have access to the server to allow it. I have replaced the url with googleapis as an example here.
const url = 'https://www.googleapis.com/storage/v1/b/example-bucket/o/foo%2f%3fbar';
const yUrl = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%3D%22' + encodeURIComponent(url) + '%22&format=json';
fetch(yUrl)
.then(function(response){
alert(JSON.stringify(response, null, 4));
})
If we open the yUrl in browser itself, it works fine: http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%3D%22https%3A%2F%2Fwww.googleapis.com%2Fstorage%2Fv1%2Fb%2Fexample-bucket%2Fo%2Ffoo%252f%253fbar%22&format=json
However the response alerted (and thus returned) to fetch is empty.
Kindly guide me in the right direction. Thanks.
P.S. I don't want to use jQuery, would prefer JavaScript.
A fetch(…) call returns a promise containing a response object, and to get the JSON from that, you need to use the .json() method, which returns a promise containing the JSON.
So all together to see the serialized JSON data, you need to do something like this:
fetch(yUrl)
.then(response => response.json())
.then(json => JSON.stringify(json))
.then(function(json) {
alert(json);
})