How can I merge results from multiple REST endpoints? - javascript

I am new to Express.
I am creating a new API endpoint, which is getting data from two other publically available endpoints. Once I get the JSON from both APIs, I will merge them according to some rules.
let result1, result2;
// API 1
let data1;
app.get("/test1", (req, res, next) => {
axios.get("https://www.EXAMPLE.com/api/endpoint_A")
.then((response) => {
res.json(response.data)
data1 = response.data;
});
});
// API 2
let data2;
app.get("/test2", (req, res, next) => {
axios.get("https://www.EXAMPLE.com/api/endpoint_B")
.then((response) => {
res.json(response.data)
data2 = response.data;
});
});
console.log(data1); //output is undefined
console.log(data2); //output is undefined
I can see result of successful calls in both the browser and in Postman.
My problem is, that I cannot find a way to manipulate the result of each endpoint. I have tried to store like this result1 = response.data in the then but it is undefined. Once I can access the output of each response, then I have to merge them. But accessing the results outside the axios call appears to be more difficult. I don't have to use axios.
I also tried this but it didn't work.
// API 1
const data1 = app.get("/test1", (req, res, next) => {
axios.get("https://www.EXAMPLE.com/api/endpoint_A")
.then((response) => res.json(response.data));
});
console.log(data1); //output is undefined

as far as im aware data does not persist between api calls. you could combine that into a single endpoint.
//Both apis into one endpoint
app.get('/test', (req, res, next) => {
const promiseArr = [axios.get('https://www.EXAMPLE.com/api/endpoint_A'),
axios.get('https://www.EXAMPLE.com/api/endpoint_B')];
Promise.all(promiseArr).then(responses => {
const resultsFromEndpointA = responses[0];
const resultsFromEndpointB = responses[1];
//do what you want with your results here... for example..
return res.status(200).json({resultsFromEndpointA, resultsFromEndpointB});
//or do something like load them into a session
req.session.results = {resultsFromEndpointA, resultsFromEndpointB};
next();
}).catch(err => {
console.log(err);
});
};

If you are getting an array of objects with the same properties from the both endpoints, do this;
let results = [];
// API 1
app.get("/test1", (req, res, next) => {
axios
.get(
"https://www.EXAMPLE.com/api/endpoint_A"
)
.then((response) => {
results.push(response.data);
});
});
// API 2
app.get("/test2", (req, res, next) => {
axios
.get(
"https://www.EXAMPLE.com/api/endpoint_B"
)
.then((response) => {
results.push(response.data);
});
});

Related

Send Map in express res.send

I'm working on a game with a friend and we need to send a Map with some stuff in it, but express only sends the user {} instead of the actual Map. The problem is at sending it and not the code itself, console.log'ging it does return the Map.
Code:
router.get("/list", async (req, res) => {
try {
const users = await userCollection.find();
accessedListEmbed(req);
let userData = new Map();
users.forEach((user) => userData.set(user.userName, user.status));
res.send(userData);
console.log(userData);
} catch (error) {
res.send("unknown");
}
});
Generally, you can only send serializable values over the network. Maps aren't serializable:
const map = new Map();
map.set('key', 'value');
console.log(JSON.stringify(map));
Either send an array of arrays that can be converted into a Map on the client side, or use another data structure, like a plain object. For example:
router.get("/list", async (req, res) => {
try {
const users = await userCollection.find();
accessedListEmbed(req);
const userDataArr = [];
users.forEach((user) => {
userDataArr.push([user.userName, user.status]);
});
res.json(userDataArr); // make sure to use .json
} catch (error) {
// send JSON in the case of an error too so it can be predictably parsed
res.json({ error: error.message });
}
});
Then on the client-side:
fetch(..)
.then(res => res.json())
.then((result) => {
if ('error' in result) {
// do something with result.error and return
}
const userDataMap = new Map(result);
// ...
Or something along those lines.

why I am getting undefined when I try to access on my property in node js

I have sent data from frontend to backend when I console what type of requests I have gotten I can see the data is showing into the console but when I try to access those properties I got undefined. I have also tried with a query, body but both get undefined when I try to access the property.
Backend code:
// DELETE SHORT URL
app.delete('/delete/:shortUrl', async (res, req) => {
console.log(req);
console.log(req.params, 'req.params');
})
Frontend:
// DELETE
const deleteUrl = (id) => {
fetch(`http://localhost:5000/delete/${id}`, {
method: 'DELETE'
}).then(res => res.json())
.then(data => {
console.log(data);
if (data.deletedCount) {
alert('Order Deleted')
// const remainingOrders = orders.filter(order => order._id !== id)
// setOrders(remainingOrders)
}
})
.finally(() => setLoadings(false))
}
Based on the Express documentation, the route callback's parameters (req & res) are reversed, so you should have:
app.delete('/delete/:shortUrl', (req, res) => {
console.log(req);
console.log(req.params, 'req.params');
})

Get request query parameters aren't applying

I'm trying to use query parameters in a get request in Express, but there are no parameters in the request body
On the frontend
query () {
if (window.location.href === 'http://localhost:3000/profile') {
window.location.href = `?contributer=${localStorage.getItem('username')}`;
}
fetch('http://localhost:3002/get-user-recipes')
.then(response => response.json())
.then(data => {
this.setState({
apiResponse: data
});
});
}
and on the backend
app.get('/get-user-recipes', (req, res, next) => {
console.log(req.query); // returns {}
});
Ok I figured it out. The parameters need to go in the express path, so the correct code is
fetch(http://localhost:3002/get-user-recipes?contributer=${localStorage.getItem('username')})
Query Params are usually at the end of a url and are initiated with a ?
Example:
// On the frontend
Making a get request to say :
http://localhost:3002/get-user-recipes?one=1&two=2
The query Params here are one with value of '1' and two with a value of '2'
// On the backend
app.get('/get-user-recipes', (req, res, next) => {
console.log(req.query); // would return { one: '1', two: ,'2' }
});

GET request from a local server not working

I am trying to obtain json files with axios' GET request, but the information is not retrieved.
In index.js (retrieving information):
axios.get('http://localhost:1000/getpost/')
.then((response) => {
console.log(response);
});
Backend endpoint getpost.js (sending information):
var router = require('express').Router();
var Posts = require('../models/post-model.js');
router.route('/').get(() => {
Posts.find({color: "Green"})
.then((res) => {
return res;
});
});
module.exports = router;
I have also tried return Posts.find({color: "Green"}); inside the router.route('/').get... function,
but the value returned is different compared to the one in the promise which is the one I need. I checked that the information is actually sent with console.log(res), but it is not received in the frontend--when I log the result there, it is null.
You are not doing anything with the route response. Maybe something like...
router.route('/').get((req, res1) => {
Posts.find({color: "Green"})
.then((res) => {
res1.end(res);
});
});
(assuming res is the data in plaint text, if it is a JavaScript object you'll do res1.json(res) or res1.jsonp(res))
You need to map the route to getpost as:
router.route('/getpost')
So your getpost would be as:
var router = require('express').Router();
var Posts = require('../models/post-model.js');
router.route('/getpost').get(() => {
Posts.find({color: "Green"})
.then((res) => {
res.send({status:200,message:res});
});
});
module.exports = router;
Apparently, I was not passing the result properly.
The router in getpost.js should be:
router.route('/').get((req, res) => {
Posts.find({color: "Green"})
.then((posts) => res.json(posts));
});

How to make call to external api from nodejs

Hi all I have to develop a utility which makes a call to external API with different parameters, for example, I have an array val which has 100 value val= ['we23','22ww', 'gh22'....n] and URL: www.google.com so one by one I have to append value from val to the URL, first api= www.google.com/we23, second api= www.google.com/22ww and make an External API hit and then store the response in database. so what is the most efficient way to do it? and links to working examples would be helpful.
A very simple example express app using the Fetch API:
const express = require('express')
const fetch = require('node-fetch')
const app = express()
// This sets up a route to localhost:3000/random and goes off and hits
// cat-fact.herokuapp.com/facts/random
app.get('/:apiRoute', async (req, res) => {
try {
const { apiRoute } = req.params
const apiResponse = await fetch(
'https://cat-fact.herokuapp.com/facts/' + apiRoute
)
const apiResponseJson = await apiResponse.json()
// await db.collection('collection').insertOne(apiResponseJson)
console.log(apiResponseJson)
res.send('Done – check console log')
} catch (err) {
console.log(err)
res.status(500).send('Something went wrong')
}
})
app.listen(3000, () => console.log(`Example app listening on port 3000!`))
Visit http://localhost:3000/random
With the following code you can make concurrent API calls within an endpoint using Node.js + Express:
const [
LoMasNuevo, LoMasVisto, TeRecomendamos, Categorias,
] = await Promise.all([
numerosController.getLoMasNuevo(),
numerosController.getLoMasVisto(),
numerosController.getRecomendaciones(),
categoriasController.getCategorias(),
]);
Inside every get function you can make an axios request like this:
const params = {
method: 'GET',
url: 'https://development.api.yodlee.com/ysl/transactions',
headers: {
'Api-Version': '1.1',
Authorization: `Bearer ${tokenuser}`,
},
};
const data = await axios(params);
return data;
In 2022
In Node.js:
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) =>
fetch(...args));
app.get('/checkDobleAPI', async (req, res) => {
try {
const apiResponse = await fetch(
'https://jsonplaceholder.typicode.com/posts'
)
const apiResponseJson = await apiResponse.json()
console.log(apiResponseJson)
res.send('Running 🏃')
} catch (err) {
console.log(err)
res.status(500).send('Something went wrong')
}
})
You can use Express to build a API as your idea
Then you can call api by using axios package.
In addition, you can build link to receive request and send response by using Router of ExpressJS

Categories