How to use http request headers in Got? - javascript

I have a very simple goal in mind. I want to make an API request from an API known as Zomato from my node.js server application. I'm using an https request framework known as Got, which is supposed to be a lighter version of request API.
var got = require('got');
var httpheaders = {
'Accept': 'application/json',
'user-key': '**********************',
'json': true
}
got('https://developers.zomato.com/api/v2.1/geocode?lat=35&lon=34', {httpheaders}).then(response => {
console.log('We got something');
console.log(response.body);
}).catch(error => {
console.log('We got nothing');
});
When I attempt to run this I catch an error and print, "We got nothing". I don't seem to know how to actually include http request headers, but I can't figure out what the proper syntax would be based off the documentation. Any help would be appreciated. Thanks!

https://github.com/sindresorhus/got/blob/HEAD/documentation/2-options.md
You could use options, like this
import got from 'got';
const options = {
headers: {
foo: 'bar'
}
};
const data = await got(url, options).json();

Related

Getting this error message 'TypeError: Failed to fetch'

While trying to fetch images from cloudinary getting this error 'TypeError: Failed to fetch'. Its a MERN project.
const fetchPosts = async () => {
setLoading(true);
try {
const response = await fetch("http://localhost:8080/api/v1/post", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (response.ok) {
const result = await response.json();
setAllPosts(result.data.reverse());
}
} catch (err) {
alert(err);
} finally {
setLoading(false);
}
};
This is likely an issue with what you're receiving from the backend. Check CORS headers, the HTTP method the backend expects, the URL, etc.
See this link for some more possible answers: https://bobbyhadz.com/blog/javascript-typeerror-failed-to-fetch-cors
Failed to fetch issue is the most probably because of CORS , please make sure that your backend should allow requests from your domain. Also please check the response that has been sending from backend api.
My IP address wasn't added to mongodb, once it was added the issue got resolved.

Netlify function: GitHub API proxy request fails with `error decoding lambda response: json`

This Netlify function should run as an endpoint on example.com/.netlify/functions/github and is supposed to proxy a fetch request from my website, reach out to the GitHub API and send data back to the website.
As far as I have understood, I can use to GET data from the GitHub API without authentication. Hitting their API directly in the browser works: https://api.github.com/orgs/github/repos?per_page=2 (also works from Postman).
The data is an array of objects where each object is a repository.
There has been multiple issues the past couple of years where Netlify functions (running on AWS lambdas) have had hickups that resulted in error messages similar to mine, so I'm confused whether this is an error in my code or something weird on their side.
First, the proxy function which – according to the Netlify admin console – runs without error. In a support article Netlify requires the result returned as JSON.stringify(), so I follow that convention here:
const fetch = require('node-fetch')
const url = 'https://api.github.com/orgs/github/repos?per_page=2'
const optionsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type'
}
const fetchHeaders = {
'Content-Type': 'application/json',
'Host': 'api.github.com',
'Accept': 'application/vnd.github.v3+json',
'Accept-Encoding': 'gzip, deflate, br'
}
exports.handler = async (event, context) => {
if (event.httpMethod === 'OPTIONS') {
return {
'statusCode': '200',
'headers': optionsHeaders,
}
} else {
try {
const response = await fetch(url, {
method: 'GET',
headers: fetchHeaders
})
const data = await response.json()
console.log(JSON.stringify({ data }))
return {
statusCode: 200,
body: JSON.stringify({ data })
}
} catch (err) {
console.log(err)
}
}
}
Client fetch that hits https://example.com/.netlify/functions/github. URL is correct, the function is executed (verified that in the Netlify admin panel):
const repos = document.querySelectorAll('.repo')
if (repos && repos.length >= 1) {
const getRepos = async (url) => {
try {
const response = await fetch(url, {
method: "GET",
mode: "no-cors"
})
const res = await response.text()
// assuming res is now _text_ as per `JSON.stringify` but neither
// that nor `.json()` work
console.log(res[0].name)
return res[0].name
} catch(err) {
console.log(err)
}
}
const repoName = getRepo('https://example.com/.netlify/functions/github')
repos.forEach((el) => {
el.innerText = repoName
})
}
Not 100% sure where this error message originates from, it is probably not the console.log(err) although it displays in the browser console, because the error code is 502 and the error also shows up directly in the response body in Postman.
error decoding lambda response: error decoding lambda response: json: cannot unmarshal
string into Go value of type struct { StatusCode int "json:\"statusCode\""; Headers
map[string]interface {} "json:\"headers\""; MultiValueHeaders map[string][]interface {}
"json:\"multiValueHeaders\""; Body string "json:\"body\""; IsBase64Encoded bool
"json:\"isBase64Encoded,omitempty\""; Metadata *functions.Metadata
"json:\"metadata,omitempty\"" }
Haven't found any clear information on this issue, could any of you enlighten me?
The only response that don't comply with the schema is the preflight request. From the error message, I assume you need to change:
'statusCode': '200',
to
'statusCode': 200, // StatusCode int
Even better, because there's no content, you may want to use 204 instead.
If that's still not enough, I may still want to include the body there as well, as it doesn't seem optional:
return {
'statusCode': 204,
'headers': optionsHeaders,
'body': ''
}

issue with making a call using fetch and jwt

*My goal here is to get the location of bikes from a bike-sharing company's API.
I did Steps 1 and 2 using Postman. but ill try to integrate it into my code once I get the hang of it.
The first step is to verify your email and generate an Auth token. This requires only a verifiable email address. Make a POST request to https://web.spin.pm/api/v1/magic_links with the body:
{"email": "sampleemail#gmail.com"}
From there, you will need to find the token within your email. This token needs to be sent with a POST request to
https://web.spin.pm/api/v1/auth_tokens with the body:
{
"grant_type": "magic_link",
"magic_link": {
"email": "<email>",
"token": "<token>"
}
}
This request returns a JSON that looks like this: {"jwt":"eyJ0eXAiOiJ.....cXVLw","refreshToken":"2cb07....bab5030","existingAccount":false}
To get the position of vehicles so a GET-Request to https://web.spin.pm/api/v3/vehicles?lng=-77.0146489&lat=38.8969363&distance=&mode= User Header Authorization: Bearer to Authenticate and use the jwt-Token we got from the Auth request.
You will get something like this as return JSON {"vehicles":[{"lat":37.69247,"lng":-122.46595,"last4":"3595","vehicle_type":"bicycle","batt_percentage":null,"rebalance":null}, … ]}
Step 3 is done using (async/awit function) using fetch where I am having the problem with. I copy-pasted the jwt in my .env file and set up the proper headers.
I get a 401 response when making the call. when I tested step 3 using postman everything seems to work fine.
I have attached a screenshot of the error in this post. Hopefully its more clear, Thanks in advance.
const fetch = require("node-fetch");
require('dotenv').config();
async function getBikes()
{
const lat = '38.897574612438575';
const lng = '-77.01855164084469';
const api_url = `https://web.spin.pm/api/v3/vehicles?lng=${lng}&lat=${lat}&distance=&mode=`;
const jwt_key = process.env.BERER_KEY;
try{
const config = { method: 'GET',
headers: {json: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer'+ jwt_key
} },
rejectUnauthorized: false
};
const response = await fetch(api_url,config );
const data = await response.json(); //response.json() //headers //.jwt; //response.json()
if (response.ok)
{
console.log("STATUS CODE IS: "+response.status);
console.log('My JWT:', response);
return data;
}
else{
console.log("something went wrong ");
console.log("STATUS CODE IS: "+ response.status);
console.log( response);
}
} catch (error) {
console.log(error);
}
}
const y = getBikes();
console.log(y)
BEARER_KEY=eyJhbGciOiJIUzI1NiJ9.eyJ1c2V

Feedly API is returning session expired instead of letting me access the API from local node environment

Using feedlys api with a node wrapper suggested from feedly to access its api. I am not getting successful logins. I have scoured the docs and any resources available and cannot find any answers so I'm reaching out to the stack overflow community to see if anyone has had experience with this platform.
I tried clearing the cache. I've tried using the fetch api instead of using the node wrapper I am trying to implement.
I installed the node package 'feedly'.
added this code to my server:
const Feedly = require('feedly')
const f = new Feedly({
client_id: 'client_id here',
client_secret: 'client_secret here',
base: 'https://cloud.feedly.com/v3/collections/',
port: 8080
})
async function feedlyStream() {
const results = await f.reads()
return console.log('results', results)
}
feedlyStream();
It does take me to a page to log in, presumably this is the auth so then i can retrieve data.
I'm not a backend user and primarily front end so performing the task this way is new to me.
When i run nodemon ./server.js from the console, it takes me to a login page, like that of feedlys website but then I get the error 'session expired'. There is no other errors, not in the console etc.
I can get retrieve information when working with insomnia to test the api endpoints, with the same exact info as above plus a bearer token.
Here is the fetch version i have tried with is very similar to that of the insomnia input.
const URL = 'https://cloud.feedly.com/v3/collections/'
const proxyurl = "https://cors-anywhere.herokuapp.com/";
window.onload = () => {
fetch(proxyurl + URL, {
credentials: 'same-origin',
Accept: 'application/json',
headers:
{
'Authorization': 'Bearer TOKEN GOES HERE',
'Access-Control-Allow-Origin': 'include',
'Content-Type': 'application/json',
"client_id": "client_id here",
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(function (data) {
console.log('data from api', data.body);
const here = document.getElementById("here")
const bodyText = () => {
if (data.body == null) {
return "Nope, it's null"
}
return data.body;
}
here.innerHTML = bodyText();
})
}
This is what i receive from the console log above
data from api ReadableStreamlocked: false__proto__: ReadableStream
Any help will be greatly appreciated. Thank you.
quite simply i was missing part of the fetch. I needed to transform the response into JSON. Not use to fetch or apis still and this was an obvious but annoying one.
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(res => res.json();) // this is what i needed to add in :)
.then(function (data) {
console.log('data from api', data.body);

Basic authentication (or any authentication) with fetch

Couldn't find any documentation on this, so before I dig deep in code does anyone out there know how to use basic authentication when making a REST request using 'fetch' (https://github.com/github/fetch).
Just tried the following line, but the header was not set in the request:
fetch('http://localhost:8080/timeEntry', {
mode: 'no-cors',
headers: { 'Authorization': 'Basic YW5kcmVhczpzZWxlbndhbGw=' }
})
.then(checkStatus)
.then(parseJSON)
.then(function(activities) {
console.log('request succeeded with JSON response', data);
dispatch(activitiesFetched(activities, null));
}).catch(function(error) {
console.log('request failed', error);
dispatch(activitiesFetched(null, error));
});
The username and password is my own first and last name, using curl it works.
If I put { 'Accept' : 'application/test' } Accept is set, just not Authorization... strange.
Just for me to able to continue I added credentials: 'include' which makes the browser to prompt for username and password which is used for communicationg with the REST backend. Just for testing, will use OAuth further on.
fetch('http://localhost:8080/timeEntry', {
mode: 'no-cors',
credentials: 'include'
})
.then(checkStatus)
.then(parseJSON)
.then(function(activities) {
console.log('request succeeded with JSON response', data);
dispatch(activitiesFetched(activities, null));
}).catch(function(error) {
console.log('request failed', error);
dispatch(activitiesFetched(null, error));
});
no-cors mode prevents the headers from being anything other than simple headers.
"Authorization" header doesn't fit to simple headers. See more here: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode
Note that if you use fetch with Authorization header you will NOT establish a session. You will have to manually add that header for every request. Navigating to secured path would also not be possible.
So to make this work You should pre-authenticate with XMLHttpRequest. You can do this like so:
var authUrl = location.origin + '/secured-path/';
var http = new XMLHttpRequest();
http.open("get", authUrl, false, login, pass);
http.send("");
if (http.status == 200) {
//location.href = authUrl;
} else {
alert("⚠️ Authentication failed.");
}
Note that above is synchronous so you don't need a callback here.
So after doing this you can use fetch without headers e.g. this request should be successful:
fetch(authUrl, {
method: 'get',
}).then(function(response) {
console.log(response);
});
Since it looks like the library you are using is a polyfill for Fetch API, I'm going to work off of the assumption that the syntax should carry through as well.
The samples I found on Mozilla's page indicate that the fetch method signature is fetch('API_ENDPOINT', OBJECT) where object looks like:
myHeaders = new Headers({
"Authorization": "Basic YW5kcmVhczpzZWxlbndhbGw="
});
var obj = {
method: 'GET',
headers: myHeaders
})
So the method becomes:
fetch('http://localhost:8080/timeEntry', obj)
.then(checkStatus)
.then(parseJSON)...
I have not tested this code, but it seems consistent with what I was able to find. Hope this points you in the right direction.

Categories