Difficulty with receiving data from axios get request - node.js

I'm running into some problems with my axios get request. I'm trying to fetch stock information using the TwelveData API. Here is my code:
const axios = require('axios');
require('dotenv').config()
const getTickerList = async() => {
await axios.get(`https://api.twelvedata.com/stocks?apikey=${process.env.API_KEY}&symbol=AAPL&country=US`).then(response => console.log(response.data));
}
When I execute that code, I get a really strange data response that I have attached: link to pic
I would appreciate any help or advice - thanks!
I have outlined the problem above: expected something not like that.

This is a known bug in Axios. The fix for now is to pin your Axios version to 1.1.3.

const axios = require("axios");
const options = {
method: 'GET',
url: 'https://twelve-data1.p.rapidapi.com/stocks',
params: {exchange: 'NASDAQ', format: 'json'},
headers: {
'X-RapidAPI-Key': 'SIGN-UP-FOR-KEY',
'X-RapidAPI-Host': 'twelve-data1.p.rapidapi.com'
}
};
const getTickerList = async() => {
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
}

In v1.2.1, it is fixed this error.
Try this
const getTickerList = async() => {
await axios.get(`https://api.twelvedata.com/stocks?apikey=${process.env.API_KEY}&symbol=AAPL&country=US`,
{
headers: {
'Accept-Encoding': 'application/json',
}
}).then(response => console.log(response.data));
}

Related

How to hide my API Key in a POST request?

I want to hide my API key when I am making a post request from my browser. I need to input a number plate and send the request to the API and the API responds me with details about it. I have managed to get this working with a GET request to another API by using nodeJS but I can't manage to make it work with a post request. Keep in mind the request needs information from my input field in the browser which is the registration number of the vehicle to send me information back about it.
Here is my function in my browser JS file.
const searchBtn = document.getElementById("search-btn")
function startFetch() {
let plate = document.getElementById("plate").value
let reg = {registrationNumber: `${plate}`}
fetch(`https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': `my key is here`,
},
body: JSON.stringify(reg),
})
.then(response => response.json())
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
};
searchBtn.addEventListener("click", startFetch);
Any help and method would be appreciated. Thanks in advance.
For anyone in the same boat. I have managed to achieve what I want.
Client side JS file:
function startFetch() {
let plate = document.getElementById("plate").value
let reg = {registrationNumber: plate}
fetch(`http://localhost:3000/v`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(reg),
})
.then(response => response.json())
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
};
And the backend using Express, NodeJS, body-parser and axios
require("dotenv").config()
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const axios = require('axios');
app.use(bodyParser.json());
app.use(express.static("src"))
//Env vars
const API_URL = process.env.API_URL
const API_KEY = process.env.API_KEY
app.post('/v', (req, res) => {
const body = req.body;
// Make a request to the backend API
axios.post(API_URL, body,
{
headers: {
"Content-Type": "application/json",
'x-api-key': API_KEY
}
}
)
.then((response) => {
// Return the response from the backend API to the client
res.send(response.data);
})
.catch((error) => {
// Handle any errors
res.status(500).send(error);
});
});
app.listen(3000, () => {
console.log('API proxy server is listening on port 3000');
});
You are already sending the body.
A very minor modification to you code:
function startFetch() {
let plate = "abc123";
let reg = { registrationNumber: `${plate}` };
fetch(`https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": `my key is here`,
},
body: JSON.stringify(reg),
}
);
}
startFetch();
You can see your api-key in the header (though you should never send secret via http):
Then in the body (in chrome they call it payload):

How to change fetch API link for deployment?

This is a method to fetch data from an API. I have used the MERN stack. I hosted this application on Heroku. The problem is that I can't understand how to change the link to fetch the API because on Heroku the app is running at a different port every time.
const SendData = async (e) => {
e.preventDefault();
await fetch('http://localhost:4000/Login',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
Email,
Password
})
})
.then(HandleErrs)
.then((res) => {
return res
}).then((res)=>{
const {UserName}=res;
// console.log(UserName);
setCredentials({
UserName,
Email,
Password
})
})
.catch((err) => {
getErr(ERR);
console.log(err)
})
}
Probably this will not give a direct answer to your question, but its a good practice,
What we normally do is create a separate file for api details
for ex:
api.js
//REACT_APP_SERVER_URL is a env variable in .env file
const rootUri = process.env.REACT_APP_SERVER_URL
? process.env.REACT_APP_SERVER_URL
: 'http://localhost:3001';
const apiVersion = 'v1';
const apiBasePath = `${rootUri}/api/${apiVersion}`; //this is the base path
export const userApis = {
all: {
url: `${apiBasePath}/users`,
method: 'GET',
},
update: {
url: `${apiBasePath}/user`,
method: 'POST',
},
};
this is how we use it
const fetchAllUser = () => {
const api = userApis.all;
fetch(api.url, {
method: api.url.method,
body: JSON.stringify(request)
}...

How do I call a different REST API within a express route?

I have an express.js REST API that I have created with a variety of routes. I'd like to create a route to call another REST API and then return the result. Ideally, it should look something like the following:
router.post('/CreateTicket', cors(corsOptions), function(req, res, next) {
//make a call to another rest api and then res.send the result
}
The REST API route that I am calling is a POST request and will take in a JSON body with the information for the ticket. It then will return a JSON response containing the ticket information and ticket link.
Essentially, I just want to pass req.body as the body of the API call and then res.send() the response of the API call. I was trying to figure out some way to use fetch or requests, but was just getting confused.
Thank you so much for any help that anyone can offer!
I would suggest to use axios if you want to call the third-party API. The simple way of doing is to create an options(config) pass it to the axios object.
npm i axios --save
Axios config
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
};
try {
const result = await axios(options);
console.log(result);
} catch (e) {
console.log(e);
}
In your route file:
const axios = require('axios');
const getData = async (body) => {
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
body
}
};
try {
const result = await axios(options);
console.log(result);
return result;
} catch (e) {
console.log(e);
}
}
router.post('/CreateTicket', cors(corsOptions), async function(req, res, next) {
//make a call to another rest api and then res.send the result
try {
const response = await getData(req.body);
res.send(response);
} catch (e) {
//wrap your error object and send it
}
}
Note: if you want to pass the data to your own created route you can use res.redirect and it will send the response back. You can check the axios details in the link above.
You would have to use something like axios or http (code originates from link):
const https = require('https')
const options = {
hostname: 'example.com',
port: 443,
path: '/todos',
method: 'GET'
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
return d
})
}

Using Sequelize Operators with values from JSON body

New to Sequelize and SQL queries in general but wondering there is a simple way to use values sent in JSON body from the client when querying the database. I tried a number of variations of the below without success.
A simple example of the server route looks like this:
builder.post('/', async (req, res) => {
let track_criteria1 = req.body.criteria1;
let track_criteria2 = req.body.criteria2;
const customPlaylist = await req.context.models.Song.findAll({
where: {
[Op.and]: [
{ criteria1: { [Op.gt]: track_criteria1 } },
{ criteria2: { [Op.gt]: track_criteria2 } }
]}
});
return res.send(customPlaylist);
});
module.exports = builder;
For context, the request from the client looks like this:
const handleSubmit = async event => {
event.preventDefault()
updateStatus(PENDING)
const response = await fetch(`http://localhost:8000/playlistbuilder/`, {
method: 'POST',
contentType: 'application/json',
body: JSON.stringify({
criteria1: state.trackCriteria.criteriaOne,
criteria2: state.trackCriteria.criteriaTwo,
})
})
const tracks = await response.json()
setcustomTracks(tracks)
setTimeout(() => {
updateStatus(SUCCESS)
}, 2000)
}
Maybe this is wishful thinking! Right now there is no error but the SQL query logs out like: WHERE ("songs"."criteria1" > NULL AND "songs"."criteria2" > NULL);
Thanks!
If anyone else ends up here. I solved it by moving the contentType into a header. The updated submit handler looks like:
const handleSubmit = async event => {
event.preventDefault()
updateStatus(PENDING)
const response = await fetch(`http://localhost:8000/playlistbuilder/`, {
headers: {
'Content-Type':'application/json'
},
method: 'POST',
body: JSON.stringify({
criteria1: state.trackCriteria.criteriaOne,
criteria2: state.trackCriteria.criteriaTwo,
}),
})
I don't know enough about this yet to explain WHY this works. I'll research that tomorrow, but it is now working.

How to rewrite this cURL command to axios code

I need to call the propublica API the call example they have is using cURL:
-H "X-API-Key: PROPUBLICA_API_KEY"
How can i rewrite it in axios.
I tried this and does not work, get an undefined response.
axios.get('"https://api.propublica.org/congress/v1/members/{house}/{FL}/current.json/X-API-Key/APIKEY '),
]).then(axios.spread((response1, response2) => {
console.log(response1.data.url);
})).catch(error => {
console.log(error);
}); ```
the -H option is to pass the option as a header, not as a query parameter or as a part of the URL. You would have to do something like this instead:
axios.get(url, { headers: { 'X-API-Key': headerKey } })
Using the RESTClient Extension for firefox, this worked for me:
https://api.propublica.org/congress/v1/116/senate/members.json
with in Header X-API-Key:my-personal -key.
So using axios, you may use:
let url = 'https://api.propublica.org/congress/v1/116/senate/members.json';
axios.get(url,
{
headers: {
'X-API-Key': headerKey
}
}
)
.then (res=>console.log(res))
.catch(err => console.log(err));
This is working, thanks for the answers.
const axios = require('axios');
axios.request({
url: "https://api.propublica.org/congress/v1/members/house/FL/current.json",
headers: { 'X-API-Key': "API-KEY" },
method: 'get'
}).then(response => {
// console.log(response.data.url);
console.log(response.data)
}).catch(error => {
console.log(error);
});

Resources