I am trying to fetch API data using Node JS. I am using this node package to do so.
https://www.npmjs.com/package/cryptocompare
The documentation of that package is easy enough.
global.fetch = require('node-fetch')
const cc = require('cryptocompare')
cc.price('BTC', ['USD', 'EUR'])
.then(prices => {
console.log(prices)
})
.catch(console.error)
I've tested it with npm.runkit.com and it works.
However, when I install the package into my app, I don't see any output in the console.
I am using JetBrains WebStorm and these are the steps I've taken.
Create New Express App
npm install -g express-generator
npm install --save node-fetch
npm install --save cryptocompare
npm install
Then within /routes/index.js I added the following
var express = require('express');
var router = express.Router();
global.fetch = require('node-fetch');
const cc = require('cryptocompare');
/* GET home page. */
cc.price('BTC', ['USD'])
.then(prices => {
console.log(prices)
}).catch(console.error);
router.get('/', function(req, res, next) {
res.render('index', {
title: 'Example'
});
});
module.exports = router;
But that displays nothing in the console log. I tried moving the global.fetch to app.js in the root directory but that didn't do anything either.
What am I doing wrong here?
var express = require('express');
var router = express.Router();
global.fetch = require('node-fetch');
const cc = require('cryptocompare');
/* GET home page. */
router.get('/', function(req, res, next) {
cc.price('BTC', ['USD'])
.then(prices => {
res.render('index', {
title: prices
});
}).catch(console.error);
});
module.exports = router;
This will work for you
Not sure why you are not getting anything. I tried with same steps and got the result.
I just did one thing differently, i pasted whole code in a file named as abc.js.
and then i ran it in command line like this
node abc.js
and i got this result
{ USD: 2797.06 }
Can you please try it again because its working awesome for me. Let me know if you face any problem.
Continue...
So if you want to use it in index.js then you can do something like this
cc.price('BTC', ['USD'])
.then(function(prices){
console.log(prices)
}).catch(function(error){
console.log(error);
});
I just changed its syntex from es6 to es5
Related
The normal get method works fine on my main server.js file. I also use server.get('/favicon.ico', (req, res) => res.status(204)); to tackle the issue of the favicon request. It works well, again only on my main server.js file.
When I try to separate the code, by creating a user.js file that handles the api calls, I get:
::ffff:127.0.0.1 - GET /favicon.ico HTTP/1.1 404 150 - 1.669 ms
::ffff:127.0.0.1 - GET /users HTTP/1.1 404 144 - 0.454 ms
This is my main file - server.js:
const express = require('express');
const morgan = require('morgan');
const server = express();
const router = require('../routes/user');
const mysql = require('mysql');
server.use(morgan('short'));
//server.use(express.static('../public'));
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
router.use(router);
server.get('/', (req, res) => {
console.log("Test!");
res.send("This works!");
});
//server.get('/favicon.ico', (req, res) => res.status(204));
server.listen(3003, () => console.log('Program is running! Port: 3003'));
This is my user.js file:
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
router.get('/users', (req, res) => {
res.send('Hello');
});
router.get('/favicon.ico', (req, res) => res.status(204));
module.exports = router;
I'm not sure if this is related but I also experience the same problem when trying to server.use(express.static('../public')). It doesn't work. I cannot serve my html file. I've tried using the csp headers when requesting but that doesn't work. Setting up a CSP policy in the html header meta tag is not working either.
These are the versions of certain modules and technologies if you see a problem in any of their versions:
Apache 2.4.39
Node 6.9.0
Windows 7 - Yeah I know but bear with me
If anyone can help with eigther the router issue or the static file server issue it would much appreciated.
Thank you.
A simple way to do this is, in your server.js file add
server.use("/user", require("./routes/routes"));
note: routes is a folder here and routes.js is a file inside that folder.
then in your route.js file add
const express = require('express');
const router = express.Router();
const user = require('../controllers/user.controller');
// register controllers
const userController = new user();
userController.register(router);
module.exports = router;
pass your router in the user register(router) method. and it will be easily accessible in your user.js file.
I am attempting to deploy a Vue.js, Node, Express, MongoDB (MEVN) stack application to Netlify. I successfully deployed the front end of the application to Netlify, and am now attempting to deploy the express server, based on the following serverless-http example: https://github.com/neverendingqs/netlify-express/blob/master/express/server.js
I configured my server to include the serverless-http package:
server.js
const express = require('express');
const app = express();
const serverless = require('serverless-http');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');
const postRoute = require('./routes');
mongoose.connect(config.DB, { useNewUrlParser: true, useUnifiedTopology: true }).then(
() => { console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/messages', postRoute);
app.use('/.netlify/functions/server', router); // path must route to lambda
app.use('/', (req, res) => res.sendFile(path.join(__dirname, '../public/index.html')));
module.exports = app;
module.exports.handler = serverless(app);
routes.js
const express = require('express');
const postRoutes = express.Router();
// Require Post model in our routes module
let Post = require('./post.model');
// Defined store route
postRoutes.route('/add').post(function (req, res) {
let post = new Post(req.body);
post.save()
.then(() => {
res.status(200).json({'business': 'business in added successfully'});
})
.catch(() => {
res.status(400).send("unable to save to database");
});
});
// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
Post.find(function(err, posts){
if(err){
res.json(err);
}
else {
res.json(posts);
}
});
});
module.exports = postRoutes;
I then re-deployed my application to Netlify, but the server does not seem to run in Netlify. This server is in a folder in project root of my vue.js app. Should I instead run the server as a separate site in Netlify? If not, what should I do in order to get the server to run when deployed in Netlify?
It's been a while, but here goes.
Netlify hosting is for the Jamstack, as they say, i.e. only static files, no processing on the server. The idea is to make use of other mechanisms to get your data dynamically, such as APIs hosted elsewhere, which you query straight from the browser, or when you build your site.
Most likely you actually had to deploy your express.js app as a Netlify Function, instead. Check Netlify's blog post on running express apps on their functions.
I had a similar issue, just that my server wouldn't connect to the routes locally, the major difference between my code and yours was that I had to do
const router = express.Router()
and then switched app.use() with router.use()
Like I said, that's for when the localhost says "cannot GET /* a defined path */"
P.S. As a side note, you don't need explicit bodyParser in recent express, express.json() works fine instead.
I am making an express web app and I am unable to import a javascript file.
In board.js, I have a line const utility = require('./utility');. This statement gives an error: ReferenceError: require is not defined.
VSCode suggests to convert const utility = require('./utility'); to an ES6 module. The result after accepting that suggestion is: import { generateRandomData } from './utility';.
If I do this, the previous error goes away but a new error appears SyntaxError: import declarations may only appear at top level of a module.
This is the folder structure of the project:
server.js:
const express = require("express");
const app = express();
const path = require('path');
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log("server started")
});
app.use(express.static(path.join(__dirname + '/public')))
app.get('/', (req,res) => {
res.sendFile(__dirname + "/index.html")
});
utility.js:
const hello = () => {
console.log('hello');
}
module.exports.hello = hello;
How else am I supposed to import javascript files in board.js?
Your public directory is made static via express.static in your server.js. Therefore, calling a public file from client-side will not pass by express but by the client's browser.
If your JS is played directly within a browser, instead of require you should use import and export.
<script src="utility.js"></script>
I added this line in index.html and it solved the problem.
Edit: Sorry, I thought I pasted the line.
Introduction
So far I have three files, one test.js is a file where I have built three functions that work.
But now I am trying to structure using MVC or at least some pattern. So now I router.js and app.js
Question
Should I put my promise functions from test.js in my config.js or server.js or something else, Im just interested in how people would do this and whats the correct way of structuring NodeJS.
server.js
In here start the server and apply the routes to my app
var configure = require('./router');
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// get an instance of router
var router = express.Router();
configure(router);
app.listen(port);
console.log('Server has started!! ' + port);
// apply the routes to our application
app.use('/', router);
config.js
In here I build my routes
module.exports = function (router) {
// route middleware that will happen on every request
router.use(function (req, res, next) {
// log each request to the console
console.log(req.method, req.url);
// continue doing what we were doing and go to the route
next();
});
// home page route (http://localhost:8080)
router.get('/', function (req, res) {
res.send('im the home page!');
});
// sample route with a route the way we're used to seeing it
router.get('/sample', function (req, res) {
res.send('this is a sample!');
});
// about page route (http://localhost:8080/about)
router.get('/about', function (req, res) {
res.send('im the about page!');
});
// route middleware to validate :name
router.param('name', function (req, res, next, name) {
// do validation on name here
console.log('doing name validations on ' + name);
// once validation is done save the new item in the req
req.name = name;
// go to the next thing
next();
});
// route with parameters (http://localhost:8080/hello/:name)
router.get('/hello/:name', function (req, res) {
res.send('hello ' + req.params.name + '!');
})
// app.route('/login')
// show the form (GET http://localhost:8080/login)
.get('/login', function (req, res) {
res.send('this is the login form');
})
// process the form (POST http://localhost:8080/login)
.post('/login', function (req, res) {
console.log('processing'); // shows on console when post is made
res.send('processing the login form!'); // output on postman
});
};
test.js
In here is a list of functions that are a chain of promises getting data and API Keys
(small function, one of many that feed into each over)
var firstFunction = function () {
return new Promise (function (resolve) {
setTimeout(function () {
app.post('/back-end/test', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
res.send(login);
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
};
My recommended structure is to put everything except server.js in lib directory so all your app is lib/ plus server.js - everything else is package.json, dependencies in node_modules (created on npm install, not in the repo), .gitignore, config files for Travis, Circle, Heroku or whatever service you're using, some README.md and things like that.
Now, server.js is just bare minimum that requires lib/app:
const app = require('./lib/app');
and starts the server with something like:
const server = app.listen(app.get('port'), () => {
logger.info('%s listening on port %s', app.get('name'), app.get('port'));
});
server.on('error', (err) => {
logger.error(err.message || err);
process.exit(1);
});
where logger is some higher lever logger like Winston or something like that.
That's it. Now, lib/app.js is minimum code that loads the middleware like body parsers etc., creates the express app and sets the variables for port and name and then uses a router that is exported by lib/routes:
const routes = require('./routes');
// ...
app.use('/', routes);
The lib/app should be enough to use for testing with tools like supertest but it doesn't listen on any port - server.js does. This is important to simplify testing.
The router exported by lib/routes is used for everything and you can start with a single lib/routes.js file and then convert it to lib/routes/index.js plus several files in lib/routes as needed.
The routes only define the actual routes and input validation with a module like e.g. express-validation and register controllers that are exported by lib/controllers - that can start as lib/controllers.js and get converted to lib/controllers/index.js plus lib/controllers/*.js as needed - just like the routes.
Then I would add top level spec or test or tests directory where all of the tests go. The tests can require your lib/app to run the tests on it with no need to listen on actual TCP ports - those will test your routes with actual controllers. Other tests will require lib/util and run some unit tests on your utilities etc. Make sure to use a tool like istanbul or nyc to calculate the test coverage.
The database schemas and data models would go to lib/schemas and lib/models, some utility helpers in lib/util, some config loading code in lib/config etc.
This is quite flexible layout and works pretty well. You can start with just few files:
README.md
LICENSE.md
package.json
server.js
lib/app.js
lib/routes.js
lib/controllers.js
lib/config.js
etc. and easily convert all of the xxx.js file into xxx/index.js with entire folder of smaller xxx/*.js files as needed.
The main difference from your approach is that I recommend exporting routers and using them by higher level routers instead of passing the high level router into lower lever modules that export functions that take routers to work on.
So instead of:
const moreSpecific = require('more-specific');
const moreGeneral = express.Router();
moreSpecific(moreGeneral);
and then in more specific:
module exports = (router) => {
router.use('/abc/xyz', ...);
};
I would recommend exporting a more specific router in a file e.g. routes/abc.js:
const router = express.Router();
router.use('/xyz', ...);
module exports = router;
and then in more general router e.g. in routes/index.js:
const abc = require('abc');
const router = express.Router();
router.use('/abc', abc);
// and export the main router for other modules like app.js to use:
module.exports = router;
to have a route like /abc/xyz.
I was building another application in node locally and have now deployed it and am working on another application.
EDIT
However whenever I start node (v5) with express(v4.13) on my localhost it will just hang and not make any connections I am also on a Mac running El Capitan. All that I ever see in the console (By Console I mean the Terminal via Logging) is:
GET / -- ms --
Here is my code below for guidance.
var express = require('express');
var fs = require('fs');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParer = require('body-parser');
var path = require('path');
var app = express();
var settings = app.settings;
var env = process.env;
var entrance = require('./route/siteBase');
app.set('view engine', 'jade');
app.set('view cache', false);
app.set('views', __dirname + '/source');
app.set('/assets', express.static(__dirname + '/source/assets/'));
app.use(logger('dev'));
app.use(cookieParser);
app.get('/', function (req, res) {
res.send('Hello World!');
});
/**
* 404 Error Handler
* Creates an error object to be used and passed to pages.
* TODO move this out of the server.js
* TODO create generic 500/404 page
* NOTE this must always be the last route called (i.e. if the server cannot find any other routes this will be called)
*/
app.use(function(err, req, res, next){
// error page
res.status(500).render('error', {error : err});
});
app.use(function(req, res, next) {
// logic - TODO: Create Error handling here
// console.log(req);
res.status(404).render('error', { error: req.originalUrl });
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
module.exports = app;
please help!
Ok so after a few more hours of debugging the trace led back to some bad NPM package installs which were somehow causing the issue.
I am still not entirely sure what happened, but basically just had to start over from a fresh project and rebuild.
Thank you for the assistance.
The following things you have to keep in your mind.
install dependencies:
$ cd your_app_name && npm install
Install supervisor and use it:
npm install supervisor -g
Edit package.json file and replace below lines :
"scripts": {
"start": "supervisor ./bin/www"
},
run the app with debug mode:
$ DEBUG=your_app_name:* npm start
run app on different port with debug mode:
$ PORT=8080 DEBUG=your_app_name:* npm start
check port is already running or not:
$ netstat -anp tcp | grep 3000
$ sudo netstat -lpn |grep :3000
Kill the running port:
$ sudo fuser -k 3000/tcp
Convert HTML to Jade: here
http://html2jade.aaron-powell.com/
I hope with above information you can sort out your problem.
In express the ordering matters
You have the hello world route after the error and 404 handler.
You need to reorder them.
// even better create a routes file and include it here
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.use(function(req, res, next) {
res.status(404);
res.send('404: Page not found');
});
app.use(function(err, req, res, next){
res.status(500);
res.send('500');
});
Take a look at a express-boilerplate for more details on including routes