Express router.get fails, yet app.get works - node.js

While walking through this tutorial, I came across a problem wherein the router methods would not work. Using npm start and accessing localhost:3000/api/puppies gets a 404 error. However when I changed
var router = express.Router();
router.get('/api/puppies', db.getAllPuppies);
to
var app = express();
app.get('/api/puppies', db.getAllPuppies);
and run with node index.js, the data prints as expected. I've tried also putting at the beginning of my file
app.use(express.static(__dirname + '/api/'));
but no joy. Is this something to do with npm start? At one point I literally copy/pasted the code out of the tutorial and still I get the 404s.

A router has to be connected to your express app in order to be part of your server.
app.use(yourRouter);
Or, more commonly with a path that isolates that router's effect to just URLs that start with a specific path and the router's own URLs are relative to this path:
app.use('/somePath', yourRouter);
Without this, it's just a declared and configured router that isn't attached to any server.
Express documentation examples here.
The tutorial you reference does not appear to show this part of using a router.

Related

Express Nested Virtual Path Prefix

I need to run an angularjs application using a virtual prefix on an express server.
index.js
app.use('/foo', express.static('./index.html'))
This works in serving my index.html with the url 'http://localhost:3000/foo', but I need to use 'http://localhost:3000/foo/bar/'
I had thought this line of code would fix that issue, but it just breaks everything.
app.use('/foo', express.static('./index.html'))
Does anyone know how I can do this?
UPDATE
I have managed 'http://localhost:3000/foo/bar' by adding this
const server = express();
const app = express();
server.use('/foo/bar/', app);
But this results in a long list of 404 errors for all my js files. For example:
http://localhost:3000/app/homeCtrl.js

ExpressJS static file serve always serves the same file

I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.

Serve both static and apis in express in production

I have deployed a express/vue app to production.
I'm finding a bit difficult to serve both static files and APIs from express.
Inside expressfolder/app.js
const app = express()
const path = require('path')
const serveStatic = require('serve-static')
...
// index.html and static/css, static/js - bundle made with npm run build
const DIR_DIST = path.join(__dirname, '../../path/to/dist')
app.use(serveStatic(DIR_DIST))
...
app.get('/tests', (req, res) => {
res.send({msg: 'Hello there!'})
})
When i go to myapp.com, I see the index.html as desired.
If I type directly in the browser myapp.com/tests I see the raw msg "hello there" from express.
If i call the same route via the link inside index.html, I receive this error in chrome
(failed) net::ERR_CONNECTION_REFUSED
It's working on my local machine, so I'm sure it's some kind of messy config I haven't set properly.
Also, I don't want to be able to access /tests directly: vue-router should override that, but it's a lesser problem.
It's probably been asked before, but it's been a while and I haven't found a solution yet.
Thanks.
The error ERR_CONNECTION_REFUSED is a fundamental networking error that occurs before your server code actually gets to run so that would likely have nothing to do with your specific server code.
It probably happens because you have a bad URL in your web page.

Converting Node.js command line app to web app

So this is more of an open ended question: I've started working with node and I've been creating command line applications for practice. The majority of these apps take command line arguments and make http requests to an API and serve up the results based on the arguments passed. The thing is, I would like these programs to have useful front-end interfaces so that the results are not just display via the command line terminal. Is there an easy way to accomplish this? Is this what Express is useful for?
perhaps more fully, that's what express is for and that's what routes do for you - so that your browser can be directed to a default (e.g. index.html) page or a specific page or service. If you're rendering basic html pages, stored in an /HTML folder, to the user, then you might have the following kind of code in your app:
var express = require('express');
var app = express();
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/HTML'));
followed by a series of app.get('path/from/browser') and/or app.post('path/from/broswer') statements which tell your nodejs server what to do when various get and post commands are sent to the app.
as your app gets more complex, you may want to consider the router service as a way to structure your application code and associated services.
you also need to start an http server, so the browser can actually talk to the server. You would do that in a very simple way by executing the following code:
var cfenv = require('cfenv');
var appEnv = cfenv.getAppEnv();
app.set('port', appEnv.port);
var server = app.listen(app.get('port'), function() {console.log('Listening on port %d', server.address().port);});
In this simple example, your app is now using 3 new services: express, ejs, and cfenv. You would use the standard npm install process to get this into your local app so that you can use them. From your application root folder, you would execute npm install --save express, repeating for each of the three new services.

Can't see console.log in routes.js using node webkit and express

I am developing a desktop app using node webkit and express. I use sublime build system to debug. I can see client pages log. But in routes I can't see any logs or alert message in sublime console, cmd console and nodewebkit devtool.
app.post('/', function(req, res) {
console.log('Hello');
// my code
});
I am sure it's hit since my page is rendered. Sorry I am new to node-webkit. Thanks for help
It sounds like your routes file isn't being hit. Try including the following in your app.js:
var router = express.Router();
var routes = require('./app/routes.js'); //the path to your routes file
router.use('/',routes);
Also in your routes file you will need a few requires:
var express = require('express'),
app = express().Router();
As far as debugging, I use node-inspector, you can install it via npm install node-inspector. They have instructions on their page of how to use it, but it's basically similar to a Chrome inspector console, you should set a breakpoint on your route function, to see if it's being triggered.
This is documented on the Express page under the express.Router() section at the bottom of the page, you will need to include the Router function in your call to break out your routes into a different file
If that doesn't work, you can post more of your code and we can try to help out.

Resources