When I save changes to the app nodemon says 'restarting due to changes'.
But when I refresh my localhost it does not apply the changes.
Everytime I have to run nodemon app.js to see the changes in my app. Why is it happening so?
Below is the app.js code:
const express = require('express')
// create express app
const app = express();
//register view engine
app.set('view engine','ejs');
//listen for requests
app.listen(3000);
app.use((req,res)=>{
console.log('new request made');
console.log('Host:',req.hostname);
console.log('Path:',req.path);
console.log('Method:',req.method);
});
//multiple get request handlers for diff webpages
app.get('/',(req,res)=>{
const blogs = [
{title: 'Yoshi finds eggs', snippet: 'Lorem ipsum dolor sit amet consectetur'},
{title: 'Mario finds stars', snippet: 'Lorem ipsum dolor sit amet consectetur'},
{title: 'How to defeat bowser', snippet: 'Lorem ipsum dolor sit amet consectetur'},
];
res.render('index',{title:'Home',blogs:blogs}); //the path for html webpage is always relative unless provided absolute. the root dir name of the path should be specified.
});
app.get('/about',(req,res)=>{
res.render('about',{title:'About'});
});
app.get('/blogs/create',(req,res)=>{
res.render('create',{title:'Create blog'});
});
app.get('/featured',(req,res)=>{
res.send('<p>Featured page</p>');
});
//redirects
app.get('/about-us',(req,res)=>{
res.redirect('/about'); //express send this response to the browser and automatically set status code to 301.
});
//setup 404 page(this functionality always at last beacuse this displays 404 page when any of the above urls is not found)
app.use((req,res) => {
res.status(404).render('404',{title:'Error 404'});
});
package.json code:
{
"dependencies": {
"ejs": "^3.1.6",
"express": "^4.17.2"
}
}
Versions:
nodemon 2.0.15,
node v16.13.2,
npm 8.1.2
Restarting server is one thing, refreshing browser is another thing. For server watching I use nodemon. Nodemon can see when changes occur in any types of files. But nodemon cannot refresh browser page. For this We may use two additional packages - connect-livereload,livereload.
npm install connect-livereload livereload
Below example:
Folder & File structure :
app.js
const path = require("path");
const livereload = require("livereload");
const connectLivereload = require("connect-livereload");
const express = require("express");
const port = 3000;
const liveReloadServer = livereload.createServer();
liveReloadServer.watch(path.join(__dirname, "views"));
liveReloadServer.server.once("connection", () => {
setTimeout(() => {
liveReloadServer.refresh("/");
}, 50);
});
const app = express();
app.use(connectLivereload());
app.set("view engine", "ejs");
app.get("/", (req, res) => {
res.render("index");
});
app.get("/about", (req, res) => {
res.render("about", { title: "About" });
});
//listen for requests
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>ejs & express</title>
</head>
<body>
<main>
<div>
<h1>This is great and it works perfectly!</h1>
<p>Welcome to using EJS with nodemon and livereload</p>
</div>
</main>
</body>
</html>
about.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>ejs & express</title>
</head>
<body>
<main>
<div>
<h1>This is great and it works perfectly!</h1>
<p>Welcome to About Page !</p>
</div>
</main>
</body>
</html>
package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "nodemon app.js -e ejs",
"watch": "nodemon --ext ejs",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"connect-livereload": "^0.6.1",
"ejs": "^3.1.6",
"express": "^4.17.2",
"livereload": "^0.9.3"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
npm run watch
We run app.js with command npm run watch
Now it works like a charm !
Output :
Related
I have deployed my mern app to heroku, but it shows me a 404 page error when I try to navigate to the routes by entering the url. The navbar links work fine and they successfully navigate me to the signin and sign up pages, but when I click the register, login links in the forms. those links are broken and it gives me a Failed to load resource: the server responded with a status of 404 (Not Found) instead.
you can check my app at https://fullstack-restaurant-app97.herokuapp.com/
Im getting the error when Im navigating to https://fullstack-restaurant-app97.herokuapp.com/signin or https://fullstack-restaurant-app97.herokuapp.com/signup routes.
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"build": "cd frontend && npm run build",
"install-frontend": "cd frontend && npm install",
"start": "node ./src/server.js",
"server": "nodemon ./src/server.js",
"frontend": "cd frontend && npm start",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false && npm run install-frontend && npm run build"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-validator": "^6.6.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.10.0",
"multer": "^1.4.2",
"path": "^0.12.7",
"shortid": "^2.2.15"
},
"devDependencies": {
"nodemon": "^2.0.4"
}
}
App.js
import React, { useEffect } from 'react';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import Signin from './containers/Signin';
import Signup from './containers/Signup';
import Home from './containers/Home';
import './App.css';
import { useDispatch, useSelector } from 'react-redux';
import { isUserLoggedIn } from './actions';
import CssBaseline from '#material-ui/core/CssBaseline';
function App() {
const dispatch = useDispatch();
const auth = useSelector(state => state.auth)
useEffect(() => {
if(!auth.authenticate){
dispatch(isUserLoggedIn())
}
}, [])
return (
<>
<CssBaseline/>
<Router>
<Route exact path="/" component={Home} />
<Route path="/signin" component={Signin} />
<Route path="/signup" component={Signup}/>
</Router>
</>
);
}
export default App;
server.js
const express= require('express');
const app= express();
const mongoose= require('mongoose');
const env= require('dotenv').config();
const PORT= process.env.PORT || 2000;
const adminRoutes= require('./routes/admin/auth');
const restaurantRoutes= require('./routes/restaurant')
const cors= require('cors');
const path= require('path');
mongoose.connect(process.env.MONGODB_URI || `mongodb+srv://${process.env.MONGO_DB_USER}:${process.env.MONGO_DB_PASSWORD}#cluster0.e4r3t.mongodb.net/${process.env.MONGO_DB_DATABASE}?retryWrites=true&w=majority`,
{
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex:true
}).then(() => {
console.log('Database connected');
});
app.use(cors());
app.use('/public', express.static(path.join(__dirname,'uploads')));
app.use(express.json());
app.use('/api', adminRoutes);
app.use('/api', restaurantRoutes);
if(process.env.NODE_ENV=='production'){
app.use(express.static("frontend/build"))
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'frontend', 'build', 'index.html'))
})
}
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
})
I have also added the link to my github repo https://github.com/codinghamster12/fullstack-restaurant-webapp
I have tried to fix this for days now and I would really appreciate if someone could look into it.
Thanks!
I cannot directly say this is the reason for happening that. But you can use a simple method to find out the problem. Navigate to the project folder and open cmd from that location. Then, login to your heroku account by using heroku login command. Then type heroku logs -t command it will show up the status of your server and API calls init. If there any error you can see the error message in red color. Then go through it you can definitely come up with a solution by using this method.
I am trying to deploy my app to heroku and I keep getting this error message saying that it "failed to detect app matching ......." and the push was rejected. I followed the way it said on the heroku website and I keep getting stuck on only that git push heroku master part I have tried doing some research I couldn't find a solution.
{
"name": "home-automation",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server/server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.15.3",
"johnny-five": "^0.11.3",
"socket.io": "^2.0.3"
}
}
Server.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var express = require("express");
var five = require("johnny-five");
var board = new five.Board({port:"COM4"});
const port = process.env.PORT || 3000;
app.use(express.static("public"))
io.on('connection', function (socket) {
console.log("New User Connected")
board.on("ready", function(){
socket.on("turnLightOn", function(data){
var led = new five.Led({
pin:"13"
});
if(data.status){
led.on();
}else{
led.off();
}
})
})
});
server.listen(port, function(){
console.log("Listening on port 3000")
});
index.js
var socket = io();
$("#toggle-light").on("click", function(){
$("#led").toggle();
if($("#led").css("display") == "none"){
var status = false
}else{
var status = true
}
socket.emit("turnLightOn", {
status
})
})
index.html
<html>
<head>
<title>Home Automation</title>
</head>
<body>
<h1>Home Automation</h1>
<button id="toggle-light">Toggle Light</button>
<div id="led" style="width:100px; height:100px; background:yellow;"></div>
<p id="moistureLevel"></p>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="/js/index.js"></script>
</body>
</html>
This means that a package.json file isn't checked into the root of your git project, so Heroku is detecting that it isn't a Node.js app. You can see this locally:
git show master:package.json
To fix it, you'll want to be sure there is a package.json in the root of your project (where there is also a .git directory), and add it to git:
git add package.json
git commit -m 'track package.json'
The phrasing ('failed to detect set buildpack') could be improved. It should probably say 'failed to detect Node.js app'. When the buildpack's "detect" script is run (https://github.com/heroku/heroku-buildpack-nodejs/blob/master/bin/detect), it looks for a package.json file to verify that there's a node app available to build.
complete Angular/MEAN beginner here - sorry in advance if I have trouble understanding any of your responses. Recently, I tried creating a web application with the MEAN stack and I used the angular-cli to create a basic project structure (ng new appName). When running npm start (which used the angular-cli command, ng serve) without any changes to the files, everything went just fine and the default "Welcome to My App!" page rendered.
But once I created my own server.js file and changed the start script to node start.js, the <app-root></app-root> component no longer rendered. There were no errors in the console or during npm start, so I wasn't quite sure where to begin.
I checked on some forums and some users said that faulty HTML could be the reason. I replaced the entire template to simply "Testing", and yet nothing would load. Others said that I had to include the static path in my server.js file with app.use(express.static(path.join(__dirname, 'src')));, but my components still would not render. I also noticed my Typescript files were not compiling to Javascript so I took care of that issue, but no avail.
I was thinking that I may be missing something in my server.js file that imports or renders the Angular components, but I can't seem to find any discrepancies between my file and samples on Github. My server.js file is posted below and hopefully someone with more experience than me can spot out what I may be missing.
var express = require("express");
var bodyParser = require("body-parser");
var mongodb = require("mongodb");
var path = require("path");
var ObjectID = mongodb.ObjectID;
var api = require('./routes/api')
var app = express();
// Body Parser Middleware.
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'src')));
app.use('/api', api);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'src/index.html'));
})
// Create a database variable outside of the database connection callback to reuse the connection pool in your app.
var db;
// Connect to the database before starting the application server.
mongodb.MongoClient.connect('the mongodb url goes here, but I have left it out for obvious security reasons', function (err, database) {
if (err) {
console.log(err);
process.exit(1);
}
// Save database object from the callback for reuse.
db = database;
console.log("Database connection ready");
// Initialize the app.
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});
package.json below:
{
"name": "mean-interact-angular2",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "node server.js",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"#angular/animations": "^4.0.0",
"#angular/common": "^4.0.0",
"#angular/compiler": "^4.0.0",
"#angular/core": "^4.0.0",
"#angular/forms": "^4.0.0",
"#angular/http": "^4.0.0",
"#angular/platform-browser": "^4.0.0",
"#angular/platform-browser-dynamic": "^4.0.0",
"#angular/router": "^4.0.0",
"body-parser": "^1.17.2",
"core-js": "^2.4.1",
"express": "^4.15.3",
"mongodb": "^2.2.28",
"mongojs": "^2.4.0",
"mongoose": "^4.10.5",
"passport": "^0.3.2",
"rxjs": "^5.1.0",
"typescript": "^2.3.4",
"zone.js": "^0.8.4"
},
"devDependencies": {
"#angular/cli": "1.1.0",
"#angular/compiler-cli": "^4.0.0",
"#angular/language-service": "^4.0.0",
"#types/jasmine": "2.5.45",
"#types/node": "~6.0.60",
"codelyzer": "~3.0.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-coverage-istanbul-reporter": "^1.2.1",
"protractor": "~5.1.2",
"ts-node": "~3.0.4",
"tslint": "~5.3.2",
"typescript": "~2.3.3"
}
}
Don't merge front-end and back-end it will increase the complexity of understanding and managing , keep both part separately like web API,
one part for your angular created by ANGULAR-CLI and another your nodejs and express.
Then it will be easy to understand and work on..
BACK-END directory structure..
Example:
1.) Server.js
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.get('*', (req, res) => {
res.render('index.html');
})
app.listen(3000, () => {
console.log('server started');
})
2.) generated index.html from angular-cli [ng-build]
copy and past index.html from dist directory to the view directory of node
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MahacelebrationFrontend</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="styles.4d731bc23993ad5ff6b1.bundle.css" rel="stylesheet" />
</head>
<body>
<app-root>Loading...</app-root>
<script type="text/javascript" src="inline.1e83bfad21d1a20819c7.bundle.js"></script>
<script type="text/javascript" src="polyfills.2024f3f29aec2a67603a.bundle.js"></script>
<script type="text/javascript" src="scripts.60ea08cac30c3ae8c3a5.bundle.js"></script>
<script type="text/javascript" src="vendor.31125e334b44bf11507e.bundle.js"></script>
<script type="text/javascript" src="main.6d7c8d757d6b638d29f5.bundle.js"></script>
</body>
</html>
3.) Keep all other generated files from ng-build into the public directory of nodejs.
and then run from the terminal
node server.js OR nodemon server.js as you wish
NOTE
1.) build directory will generate only after applying
[ng build] command.. of angular-cli
2.) There are other structure you can follow but I prefer it because of ANGULAR base path ,
This is my personal opinion , it not like, you have to follow same structure as mine. you can use as you like.
COMPELETE DIRECTORY STRUCTURE
-
Thank you ,
I hope it will help you.
I had the same problem.
I see that the path you are using is app.use(express.static(path.join(__dirname, 'src'))); which is wrong
When you compile angular project with ng build it compiles the project and writes compiled files in dist folder where a new compiled index.html will be built.
After running the ng build project you will see that dist folder contains the compiled javascript files of the typescript files.
You should send this index.html present in dist folder as a response and not the index.html in src folder.
So your code will be like this
var express = require("express");
var bodyParser = require("body-parser");
var mongodb = require("mongodb");
var path = require("path");
var ObjectID = mongodb.ObjectID;
var api = require('./routes/api')
var app = express();
// Body Parser Middleware.
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'dist'))); // see the change in this line
app.use('/api', api);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));}) // see the change in this line
// Create a database variable outside of the database connection callback to reuse the connection pool in your app.
var db;
// Connect to the database before starting the application server.
mongodb.MongoClient.connect('the mongodb url goes here, but I have left it out for obvious security reasons', function (err, database) {
if (err) {
console.log(err);
process.exit(1);
}
// Save database object from the callback for reuse.
db = database;
console.log("Database connection ready");
// Initialize the app.
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});
After making the path changes your <app-root> component will be rendered in the browser.
Another important point is that app.use() should take the argument to the of the folder which is the immediate parent folder of compiled index.html and not necessarily dist folder otherwise <app-root> component will not be rendered.
This question already has answers here:
How do I use HTML as the view engine in Express?
(16 answers)
Closed 5 years ago.
I am getting TypeError: this.engine is not a function. I don`t know why I am getting this error. Can anyone please help me to solve this issue.
My server file:
var express = require('express');
var path = require('path');
var app = express();
//configure app
app.set('view engine', 'html');
app.set('views', path.join(__dirname, 'views'));
app.get('/', function (req, res) {
res.render('index');
});
app.listen(3000, function() {
console.log('Ready on port 1337');
});
And my HTML file:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>Hello Express</div>
</body>
</html>
I get the error
My package.json:
{
"name": "app",
"version": "1.0.0",
"main": "index.html",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "mehadi",
"license": "UNLICENSED",
"dependencies": {
"express": "4.13.0",
"html": "^1.0.0"
},
"repository": {
"type": "git",
"url": "(github.com/mehadi07/Random.git)"
},
"devDependencies": {},
"description": ""
}
I installed the html engine via
npm install --save html
The html package you've installed is unrelated to Express. So it's not surprising that if you tell Express to use it, it fails.
If you're looking to serve static HTML files, see this question's answers, and the Express documentation. The simplest way is just
app.use(express.static('views'));
html package is not a template engine that can be used with Express. Instead it is a HTML pretty printer CLI utility.
Please see Using template engines with Express for a list of template engines that works fine with Express.
So i have an Angular 2 app that runs locally without problems. When deploying my app using heroku i get following errors:
>SyntaxError: expected expression, got '<'
><!DOCTYPE html>
>shim.min.js (Zeile 1)
>
>SyntaxError: expected expression, got '<'
><!DOCTYPE html>
>zone.js (Zeile 1)
>
>SyntaxError: expected expression, got '<'
><!DOCTYPE html>
>Reflect.js (Zeile 1)
>
>SyntaxError: expected expression, got '<'
><!DOCTYPE html>
>system.src.js (Zeile 1)
>
>ReferenceError: System is not defined
>systemj...nfig.js (Zeile 6, Spalte 3)
>
>ReferenceError: System is not defined
>mean1nv...app.com (Zeile 24, Spalte 7)
There are similar posts that suggest all kind of changes but i dont know where it breaks in my code. I feel kind of blind, i deployed a similar app before without problems and I cant find the difference.
server.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var items = require('./routes/items');
var app = express();
app.set('port', (process.env.PORT || 3000));
app.use(express.static(path.join(__dirname,'client')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/api', items);
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile(path.join(__dirname, './client', 'index.html'));
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
package.json (server side)
{
"name": "namex",
"version": "1.0.0",
"description": "descx",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.15.2",
"ejs": "^2.5.5",
"express": "^4.14.0",
"mongojs": "^2.4.0",
"ng2-pagination": "^1.0.1"
}
}
systemjs.config.js
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
// other libraries
'ng2-pagination': 'npm:ng2-pagination/dist/',
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'angular2-jwt': 'node_modules/angular2-jwt/angular2-jwt.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
'angular2-jwt': {
"defaultExtension":'js'
},
rxjs: {
defaultExtension: 'js'
},
'ng2-pagination': {
defaultExtension: 'js', main: 'ng2-pagination.js'
}
}
});
})(this);
index.html
<!DOCTYPE html>
<html>
<head>
<title>ngAuth0 App</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Philosopher" rel="stylesheet" type="text/css">
<script src="https://cdn.auth0.com/js/lock/10.6/lock.min.js"></script>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<base href="/">
<my-app>Loading ...</my-app>
</body>
</html>
You should copy polyfills with the app when deployed node_modules is not available.
if you copy them to the same folder where systemjs.config.js
<script src="shim.min.js"></script>
<script src="zone.js"></script>
<script src="Reflect.js"></script>
<script src="system.src.js"></script>