How to use router.get and https.get together? (Node.js) - javascript

I want to get information from the http request and send it to the frontend via the path '/ get'. I combined these 2 functions and it works but I don't think it is correct:
const router = express.Router();
const https = require('https');
router.get('/get', (req, res) => {
https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
res.json(JSON.parse(data).explanation)
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
});
Is there a better way to do this?

The better way would be to use Axios to make all your http requests to external apis which you want from nodejs application. It is a promise based request making library which you can use in browser as well as on backend server.
Install axios using npm install axios
axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY').then(response => res.send(response.data)).catch(error => console.log(error));

No, it works fine.
But if you want another way, then use axios
you need to require axios and then add your request in the router.
const axios = require('axios');
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
you get more information from here

Related

How do I make a live search result in node.js and mongoDb

I am trying to implement a feature where I have an input on this route to make a live search of employees in the database
app.get('/delete' , isLoggedIn , (req , res) => {
res.render('pages/delete')
})
This route serves the search input. How do I create a live search based on a keyup event listener that sends the data to mongoDb/mongoose to search and return the results on the page?
I know how to do the event listener to get what is typed like so which is in the delete.js file
const deleteSearchInput = document.querySelector('#search-input');
deleteSearchInput.addEventListener('keyup' , (e) => {
let search = e.target.value.trim()
})
How do I send the value "e" to a post route to do the search and return it to the page
AJAX (using the JavaScript fetch API). AJAX allows JavaScript to send requests to the server without reloading.
const deleteSearchInput = document.querySelector('#search-input');
deleteSearchInput.addEventListener('keyup' , (e) => {
let search = e.target.value.trim();
fetch('/delete', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({search})
}).then(res =>
res.json()
).then(data => {
console.log(data.result); // <-- success!
}).catch(err => {
alert('error!');
console.error(err);
});
});
Then you have changes to make to the server side. Since you're sending a POST request, you need to create a handler to POST:
app.post('/delete', isLoggedIn, (req, res) => {
res.send('success!');
});
This will handle post requests, and only post requests. Now to get the value of whatever you sent to the server, we need to use an npm package called body-parser, which parses the incoming request. Run the following command in shell:
npm i body-parser
Then at the top of your server file before declaring your routes import and use the body-parser library:
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // <-- add the JSON parser
Finally change your handler again:
app.post('/delete', isLoggedIn, (req, res) => {
const { search } = req.body;
console.log(search);
// ... do whatever you want and send a response, e.g.:
const result = 'my awesome message';
res.json({ result });
});
And that's how you do it.

Check url-redirection using axios in nodejs

I'm using axios for API calling in nodejs.
I want to check if "https://origin.com/?url=https://destination.com" this url is redirecting to "destination.com".
So which status/headers I can check in axios response.
What will be the condition to check if it goes to "destination.com"
var express = require('express');
const axios = require('axios');
var app = express();
app.get('/test', function (req, res) {
// Check if it redirects
axios.get('https://origin.com/?url=https://destination.com')
.then(response => {
console.log(response);
// Here I want to check if it redirects successfully to "destination.com"
if (condition) {
// Successfully redirected to "destination.com"
}
})
.catch(error => {
console.log(error);
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
I think you should try to use https for api, then in the response header you can find that it direct to the "destination.com".
Https is much simple and easy to use.
const https = require('https');
https.get('https://encrypted.google.com/', (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
}).on('error', (e) => {
console.error(e);
});
You can find the redirect url under responseURL key,
get fetchedUrl by
const fetchedUrl = response.request.res.responseURL;
see this
Environment node: v8.9.4 axios: ^0.18.0

Why is the fetch function saying, that I have to use absolute urls, even if I have set a proxy?

At the moment I am coding a Shopify application. I want to fetch all the products from my store in server.js but every time it outputs a message, that says that only absolute urls are supported. A registered Webhook should get all the products inside my shop.
Error: only absolute urls are supported
Here is my javascript (server.js)
const { default: proxy } = require('#shopify/koa-shopify-graphql-proxy');
const { ApiVersion } = require('#shopify/koa-shopify-graphql-proxy');
app.prepare().then(() => {
const server = new Koa();
const router = new Router();
server.use(session(server));
server.keys = [/** Shopify Keys */];
server.use(
createShopifyAuth({
/**
* Webhook
*/
}),
);
const webhook = receiveWebhook({ secret: SHOPIFY_API_SECRET_KEY });
router.post('/webhooks/products/create', webhook, async (ctx) => {
await fetch('/graphql', {
credentials: 'include',
body: allProducts
})
.then((data) => {
console.log(data)
})
.catch((err) => {
console.log(err)
})
console.log('received Webhook: ', ctx.state.webhook);
})
server.use(router.allowedMethods());
server.use(router.routes());
console.log(proxy({ version: ApiVersion.Unstable }))
server.use(proxy({ version: ApiVersion.Unstable }))
server.listen(port, () => {
console.log(`> Ready on localhost:${port}`)
})
})
I was using the example from the npm package shopify koa proxy link here
How can I send http request with the proxy I am using?
The issue is exactly what the error says, fetch requires absolute urls.
Whether you have a proxy or not is really irrelevant to the fetch api, it doesn't know about that.
Just give it an absolute URL

How do I do a GET for Firebase.functions().httpsCallable?

How do I do a GET for Firebase.functions().httpsCallable?
I keep receiving a POST error 404 but this is a GET request to my server. Should I pass in nothing or there is something to change this httpsCallable to get function?
Client
let updateWorkshop = Firebase.functions().httpsCallable('api/update/workshop');
updateWorkshop({/* nothing */})
.then(res => {
console.log(res);
}, err => {
console.log(err);
})
Server
app.get('/v3/update/workshop', asyncMiddleware( async (req, res, next) => {
let results = await UPDATE_WORKSHOP_DATE.Run()
res.status(200).json({results: results})
}))
exports.api = FUNCTIONS.https.onRequest(app);
If you are just trying to ping your callable function endpoint, a GET won't work. As you can see from the protocol specification for callable functions, it uses a POST. If you use a GET, it's an error because you're not following the protocol.

using Node.js' https.request() and outputting to a browser

Im following a article about http requests to nasa's pic of the day. I'm trying to display the JSON object in browser from my server. But all Node.js' examples outputs the api results to a server's console. is it possible to have my server save/forward the response to the browser? I'd like to understand the native http module before relying on any dependencies. Also I'm not sure if it makes a difference but I'm using express to create my server. anything will help even a high level explanation because I'm so confused.
const https = require('https');
app.get('/', (req, res) => {
var url = 'https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY';
var nasa_obj
var request = https.get(url, function (resp) {
var body = '';
resp.on('data', function (chunk) {
body += chunk;
});
resp.on('end', function () {
nasa_obj = JSON.parse(body);
console.log("Got a response: ", nasa_obj);
res.send(nasa_obj)
});
}).on('error', function (e) {
console.log("Got an error: ", e);
});
request.end()
})
UPDATED: CODE IS CORRECT
You only want to send the response once it has been returned to you:
const https = require('https');
app.get('/', (req, res, next) => {
var url = 'https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY';
var nasa_obj
var request = https.get(url, function (response) {
var body = '';
response.on('data', function (chunk) {
body += chunk;
});
response.on('end', function () {
console.log("Got a response: ", body);
res.send(body);
});
}).on('error', function (e) {
console.log("Got an error: ", e);
next(e); // Pass error to error handling middleware
});
request.end()
})
Also make sure you are properly handling errors. Either send back a response to the browser to, as the code above is doing, pass it on to error handling middleware.

Categories