Getting Console Messages on Webpage NodeJS - javascript

I'm wondering if there's any way to listen for console messages and act on console messages when they're received. Mainly, is there any way to do this without an external module, and using the http module?
The goal is to trigger a NodeJS function or code snippet on an event like click in the HTML. If there's also a way to do this, then that's great. But once again, I'd like to do this without an external module, and just use those that are built-in to NodeJS.

Use onclick() function in JavaScript to trigger a function call when clicking on a element. Then use fetch to make a api call to the nodejs server.

I know #Haris Wilson already got the answer, but I'd just like to provide a code example.
Instead of trying to catch a console message and then execute a function if we find it, we can use fetch() to make a request to whatever URL we need, and this can allow us to make other requests.
In this case, we can use the url module and the http module to parse the url and serve the API and website, respectively.
const url = require('url')
const http = require('http')
const requestListener = async function (req, res) {
// Basic server setup
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(/** Content here */)
// API
if (url.parse(req.url, true).pathname === '/APIcall') {
let arguments = url.parse(req.url, true).query
// Preform necassary actions here
}
}
We can now use onClick to call a function inside our webpage JavaScript, and use fetch([API URL]) to give our NodeJS data to preform an action. We can use URL params to do this, such as https://localhost:8080/APIcall?data=someData&moreParam=more-data, where ?data=someData&moreParam=more-data are the URL params.

Related

using stream.pipe make express middleware skipped

im using express and nodejs for my api server,
and now im implementing pdf download (im using pdf-creator-node) for converting html to pdf.
the pdf-creator-node will create a stream when converting a html, and when i pipe it, all my middleware (notFoundHandler, errorHandler,responseLogger) got skipped
router.get(
'/generatePDF', authenticate, schemaValidation({ params: generatePDFschema }),
(req, res, next) => {
generatePDF(details) {
const template = readFile('./src/templates/da-template.html');
const receipt = {
html: template,
data: payload,
type: 'stream'
};
const generatedPdf = pdf.create(receipt, advisOptions);
return generatedPdf;
}
const pdfStream = generatePDF(details);
res.setHeader('Content-type', 'application/pdf');
pdfStream.pipe(res);
},
notFoundHandler,
errorHandler,
responseLogger
);
is there any express api can i use to pipe a stream?
The middleware you show is passed to router.get() AFTER your request handler so it will not get a chance to run unless you call next() in your request handler. When you pass multiple request handlers to a router.get(), they will run sequentially in order and the 2nd one will only get a chance to run if the first one calls next(). Same for the 3rd one, and so on.
Furthermore, pdfStream.pipe(res); does not call next().
I don't know exactly what those middleware functions are supposed to do, but making a guess based on their names, perhaps they are supposed to run BEFORE your request handler, not after so they can put things in place for various error conditions.
If you want further help, then please show the code for those three middleware functions so we can see more specifically what they are trying to do.

Is it possible to pass data from node js to frontend js and not to html?

I'm trying to pass data (array) from node.js backend to frontend JS to process it there. I don't want to pass data directly to backend-served html file because I'd like to keep it clean and don't want to do any loops there etc.
My backend part looks like this:
app.get("/search-db", function (req, res) {
const term = req.query.term;
findInDb(term);
res.redirect('/search', {
searchResults: searchResults,
});
})
async function findInDb(query) {
const collection = await getDbCollection();
await collection.find().forEach((item) => {
console.log(item.artist);
if (item.artist.includes(query) || item.name.includes(query)) {
searchResults.push(item);
}
})
}
Is this possible or do I have to clutter my html and use loop there to process passed results?
Your web page can use AJAX via fetch to make the /search-db API request to your server. Your server route handler should fetch the results from the DB, then invoke res.send() to send a JSON response back to the client, rather than res.redirect() to redirect the client to a new page.
Example: How to create a REST API with Express.js in Node.js
Also, unrelated, your findInDb function should return the search results instead of placing them in a global variable (searchResults).

Accessing the data from a Node JS GET request without chaining callback functions

I'm using node.js simply so that I can run scheduled tasks and use GET requests. I'll paste some code that displays what I want to do, although it doesn't work for an obvious reason:
const http = require("http");
const request = require("request");
http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.write("Hello, World!");
let a = getRequest();
console.log(a);
res.end();
}).listen(8080);
function getRequest() {
let b;
request("http://www.google.com", function(err, res, body) {
b = body;
})
return b;
}
So the b from the body does not work due to how the request is asynchronous and this leaves b as undefined when it is eventually printed. I know the way these callback functions are supposed to be used is to keep chaining of the callback function since that's the only place where the contents of body can be accessed. However, I don't want to keep chaining off functions because it completely destroys the structure of the program. I want to keep all my node server commands inside the http.createServer block. I don't want to place them in functions called from inside the callback function. In this example it doesn't really make sense for the process to be asynchronous since there's only 1 get request anyway and it can't be displayed in console.log until it's received anyway.
I just need a simple way to scrape data with get requests. What would be perfect is if I had some function that I could give a bunch of links, it gets the raw html from them, and then it waits for them to all be done so that I can process all the data at once.
How can something like this be implemented in Node.js?
You can do that using this module: sync-request.
With this module you will be able to make synchronous web requests from your NodeJS code.

Javascript - Querying VoltDB api with fetch

I'm trying to query a VoltDB using its api:
const url = 'http://server:8080/api/1.0/'
const queryParam = encodeURIComponent('select * from table')
const queryURL = url + `?Procedure=#AdHoc&Parameters=['${queryParam}']&jsonp=console.log`
fetch(queryURL).then( response => {
response.text().then( text => console.log(text) )
})
With that code throws an "No Access-Control-Allow-Origin" error.
If I change the fetch call to this:
fetch(queryURL, { mode: 'no-cors').then( response => {
response.text().then( text => console.log(text) )
})
It does nothing
This is a browser security feature. If you are serving a web page from one url and within the page you have embedded url calls to another host or port, then the browser won't allow this.
One way to get around this is to add a proxy to your web server, so it can make the calls to port 8080, and pass the responses back to the web page from the same origin.
You may see some answers on Stack Overflow about using CORS to get around this error, but that requires changing the headers that VoltDB uses on port 8080, so that's not something you can do yourself, and we have no plans to do that.
Another solution is to use the voltdb.js file provided in some of our demos, such as the NBBO demo dashboard: https://github.com/VoltDB/voltdb/tree/master/examples/nbbo/web
I think this uses low-level javascript to open a socket to make the HTTP call without using XMLHttpRequest, so it avoids the No Access-Control-Allow-Origin error.
In the example, the code that is specific to the NBBO example is in demo.js, voltdb-dashboard.js contains code that is common to various example dashboards, and voltdb.js is the base library that provides access to call procedures asynchronously.
You should encode all the URI parameters not just the procedure parameters
$ curl --data 'Procedure=#AdHoc&Parameters=["select count(*) from store;"]' http://127.0.0.1:8080/api/1.0/
{"status":1,"appstatus":-128,"statusstring":null,"appstatusstring":null,"results":[{"status":-128,"schema":[{"name":"C1","type":6}],"data":[[100000]]}]}
or
$ curl --data 'Procedure=%40AdHoc&Parameters=%5B%22select+count(*)+from+store%3B%22%5D' http://127.0.0.1:8080/api/1.0/; echo
{"status":1,"appstatus":-128,"statusstring":null,"appstatusstring":null,"results":[{"status":-128,"schema":[{"name":"C1","type":6}],"data":[[100000]]}]}

Unexpected "write after end" error in express

I am trying to proxy an api call from client side through my server for some third party service, reasons for this being CORS issues and adding in a secret key on the server side. I usually get it done in the following way:
app.use('/someService', (req, res) => {
let url = `https://example.com/${config.SECRET_KEY}/endpoint${req.url}`
req.pipe(request(url).pipe(res))
})
this way I can use any ajax library on the client side and perform get request for example: get: '/someService/params' and it would normally go through and perform that request and then pipe it back. However now I started getting:
Error: write after end
in express and I am not entirely sure about what could be causing it.
Your piping is wrong. As it is now, you're piping to res twice (.pipe() returns the argument passed to it for chainability).
Instead try this:
req.pipe(request(url)).pipe(res)
I should point out however that properly proxying the HTTP response is not quite that simple since currently this line will always respond with HTTP status code 200, no matter what the remote server for the middle request responds with. Also, any headers from that response will not be sent to res. With that in mind, you could naively try something like:
var proxiedRes = req.pipe(request(url));
proxiedRes.on('response', function(pres) {
res.writeHead(pres.statusCode, pres.headers);
// You will want to add a `pres` 'error' event handler too in case
// something goes wrong while reading the proxied response ...
pres.pipe(res);
});

Categories

Resources