relation between front-end functions and server routes in node.js - node.js

Inexperienced with nodejs style programming, I'm looking at an open-source node.js app that has routes with the same paths in both the front-end main.js file and the routes.js file, as you see below. I'm assuming that when the function in main.js file gets called it triggers the route in routes.js, however, I can't figure out what if anything is getting passed from main.js to routes.js as a callback.
main.js
$.get('/ip', function (data) {
fp.val(fingerprint);
userId.val(md5(fingerprint + data.ip));
});
routes.js
app.get('/ip', function (req, res) {
res.json({
ip: req.connection.remoteAddress
});
});

There's nothing node-specific about the frontend script, it's just using jQuery.get to get the document at a given URL.
On the server-side, it looks like the app is using Express (or something like it) which modifies the .send() method of the response to allow sending arbitrary objects. When you send and object, Express JSON encodes it (using JSON.stringify(object) and sets the Content-Type header of the response to application/json. This content-type header is what tells jQuery to automatically parse the JSON response back into an object in the browser.
So there is no callback being passed from main.js to routes.js, it's just a bog-standard web request that sends JSON data back to the client.

Related

Post a simple react form - node, axios, nodemailer, backend, postman

I've set up a react form running on http://localhost:3000/about and I've the backend running on port 5000 (localhost:5000). On react's package.json I set up "proxy":"localhost:5000:.
When I use postman and I send the post to localhost:5000/api/contact, the email is sent correctly (I send the data as JSON - name, email and message). Status 200
When I use the react form, the data is well prepared as json but I can't figure out the baseURL to send correctly the method post. status 404. I tried:
localhost:3000/about/api/contact;
localhost:3000/api/contact;
localhost:3000/api.... None works...
FYI
the server is set up with the following middleware and is working ok:
app.use('/api',contactRoute)
the controller is imported and coded as following:
router.post('/contact', (req, res)=>{
const data = req.body;
The React part is not posting correctly with axios and is coded as following:
onSubmit: async (values) => {
//values.preventDefault();
try {
const data = (JSON.stringify(values, null, 2))
setLoader(true);
console.log(data)
await axios.post('/contact', data);
The method post in react is never completed, when I check the console.log of data, is correctly structured as JSON...status 404
use the post parameter in your axois request {port: 5000} then It will use your actual backend port.
By default, axios uses the base path from the URL. So, here when an API request is made.
await axios.post('/contact', data);
It is actually making the post request on localhost:3000 rather than your backend server at localhost:5000. Also, "api" should also be prepended.
One simple way is to use absolute URL which should work.
await axios.post('http://localhost:5000/api/contact', data);

nodejs json endpoint from api json stream

I am connecting to an api and pulling a set of json data. the javascript outputs the json as the variable feedData and when i include that in a html i get the json on a html page as expected. What i want to do is output it as a json endpoint. I tried to get fancy and when i tried:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send(feedData);
});
app.listen(3000, function () {
console.log('posting data');
});
the problem is that i need to import an api.js file and when i attempt to load this i get an error related to the api.js file which is windows is not defined. Like i said, the html
document.getElementById('mydiv').innerHTML += JSON.stringify(feedData, undefined,2);
then
<pre id="mydiv"></pre>
works fine but i will also to recall every x seconds because this is a live json feed.
Currently, i just decided to connect via python, loading it into mongodb and creating a nodejs endpoint from there, which works fine, but it seems there should be a way here.
Try using res.json, res.json(feedData); to send objects. If you want to send a string just, use res.send
Instead of
res.send(feedData);
use
res.json(feedData);
Hope this helps

Where does the /api directory come from in an Express application?

For example:
router.get('/api/todos', function (req, res){
db.todos.find(function (err, data){
res.json(data);
});
});
I am having a hard time understanding what '/api/todos/ actually means. I don't have a directory name either one of these in my application. What exactly is this and where is it?
/api/todos/ does not refer to a local file, it corresponds to a URL request. In the function you provided, if you were to add this route to an express app then visit http://localhost/api/todos, the server would respond with the JSON data returned from the database query you are making.
router.get('/api/todos', function (req, res){
This first line accepts all GET requests to /api/todos, and passes the req and res objects into a callback for you to work with. See http://www.murvinlai.com/req-and-res-in-nodejs.html for an explanation of those objects.
db.todos.find(function (err, data){
Here, it is assumed that you have a db object which may perform database lookups based on some kind of input parameters.
res.json(data);
The res.json method simply sends the JSON back to the client that requested it.
See https://www.packtpub.com/books/content/understanding-express-routes for further info on routing in express.
That's not a directory. That's a URL. Routers route URLs to resources. It could be files, it could be other URLs or most commonly it could be some javascript logic that generates the response you want (JSON, XML, HTML, PDF etc.)

How to test POST request parameters an Express app using supertest?

I'm creating an API using Express 4.0.0 and one of the routes takes a POST. Currently I'm just trying to have it echo a name sent in the request parameters. The response is a JSON object, but the request expects form fields.
users.post '/user', (req, res) ->
res.json name: req.params.name
My test sets the type() to form which should allow send() to pass the hash as POST parameters/fields.
describe 'POST /user', ->
it 'should echo the name sent', (done) ->
request app
.post '/user'
.type 'form'
.send name: 'Foo'
.expect '{"name":"Foo"}'
.end done
Regardless, my test fails and in Express, my req.params is empty, req.param('name') comes up undefined and req.body is also empty.
Is there some req.fields attribute I'm not aware of, or is my test flawed somehow?
tl;dr: You need to parse the body to get that, you can do app.use(require('body-parser')()) and then change your code with name: req.param('name').
So express(and actually node.js http server) will call the request call whenever a http request header have been received and not the body of the request. You have to explicitly read and wait for the body to come and parse it yourself.
Luckily there are express middleware modules that parses the body for you. In this case you are sending a urlencoded/form body, so you need to parse it as such. Use any of these modules according to their examples:
body-parser
body
Assuming you use body-parser, then if you want it to parse the body for all routes then just do app.use(require('body-parser')(). If you want it to parse the body for a particular route then do this:
bodyParser = require('body-parser')()
app.post '/user', bodyParser, (req, res) ->
res.json name: req.param('name')
Once you got the body parsing right, then you can access it either through req.body(for example req.body.name) property or req.param function(for example req.param('name')). The latter will also search through query string and url parameters.
Note that if you want to parse a body with attached files(for uploading files) you need a multipart parser and not just a urlencoded one:
connect-multiparty
connect-busboy

How is req and res accessible accross modules in Express.js

While using express.js for handling various routes I want to encapsulate all of my route code in a seperate module, but how can I access the req and res object across modules, See the code below
The main file examples.js is written as follows
var app = require('express').createServer();
var login = require('./login.js');
app.get('/login', login.auth(app.req, app.res));
app.listen(80);
What I want is that the login handling code be written in a seperate module/file called login.js, the question then is how will the response object be accessible in login.js. I think the following code will not work as because the type of req and res is not resolved.
exports.auth = function(req, res) {
res.send('Testing');
}
Hence when I start the server with node example.js I get the error
'Cannot call method send of undefined'
How is the Request and REsponse objects passed along modules
This should work:
app.get('/login', login.auth);
Your example was attempting to pass the return value of the login.auth function as get handler for the request. The above instead passes the login.auth function itself as the handler.
TJ Holowaychuk made some great examples for express on the github page, here's the one about route separation:
https://github.com/visionmedia/express/tree/master/examples/route-separation

Resources