Angular2 application with NodeJS not loading everything - node.js

I'm experimenting with Angular2 and, with the quick start guide on their official documentation, I'm definitely up and running. However, if I want to do any APIs on the server or host it on the cloud it seems I'll need to use Node. I think I have everything set correctly in the server.js file, yet when I run it it seems like it's not loading everything from SystemJS and I get the following errors:
Here is the Node code:
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
var System = require('systemjs');
// loads './app.js' from the current directory
System.import('app').then(function(m) {
console.log(m);
});
// Config
app.set('port', (process.env.PORT || 3000));
app.use('/app', express.static(__dirname + '/app'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(app.get('port'), function() {
console.log('MEAN app listening on port ' + app.get('port'));
});
app.get('*', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
I'm not sure what I'm missing to include in the Node side that gets included when running lite-server from npm start that is included from the Angular2 quick start guide.

When you are telling express where to look for the static files, you have to include where your js files will be as well.
For example, in one of my projects I have it like so
app.use('/css', express.static(path.resolve(appPath, 'css')));
app.use('/lib/css', express.static(path.resolve(appPath + '/lib', 'css')));
app.use('/lib/js', express.static(path.resolve(appPath + '/lib', 'js')));
app.use('/assets', express.static(path.resolve(appPath, 'assets')));
app.use('/node_modules', express.static(path.resolve(appPath, 'node_modules')));
app.use('/app', express.static(path.resolve(appPath, 'app')));
I believe that might be your issue or hopefully set you in the right path.

Related

Express + React + Heroku can't find a file

i want to get my app working on Heroku, But there is on problem. Heroku server can't find the images. On developmnt everything is working correctly. Images are loaded propertly. On heroku everything works correctly. Asking for json /api/articles gives in result json. Router also working. But images gives not found. In tag and fetch() .
code => https://github.com/bartek-fecko/cinema-app
The image file exists on heroku(i looked to the bash on heroku.com)
var express = require('express');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../client/build')));
app.use('/api', indexRouter);
app.use('/api/users', usersRouter);
app.use(express.static(path.join(__dirname, '/assets/images')));//i'm sending a file
app.get('/images/:fileName', (req, res) => {
res.sendFile(path.join(__dirname, `/assets/images/${req.params.fileName}`)); //here also i'm sending a file
});
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, '../client/build/index.html'));
});
module.exports = app;
<P.Wrapper>
<img src="spider-man-far-from-home.jpg" alt="no img"/>
<img src="/images/spider-man-far-from-home.jpg" alt="no img"/>
</P.Wrapper>
I'm getting a 404 error. And I tried everything and it doesn't work. The same for fetching fetch('/images/ ...') and so on.
From your code, you are having 2 servers:
Backend server (inside src)
Frontend server (inside client)
Since when you are starting them, they are of different servers, meaning that they either would be running on different IPs or the same IP but different Ports.
This means that your fetch of the image in the client's App.tsx would most likely be referencing the wrong host.
fetch('/images/spider-man-far-from-home.jpg')
Try using a full URL with both Host and Port in the fetch method and see if it works for you.
Yeah. woow. It's working now. The problem was exactly like Yee Hui Poh said. So in production i have to fetch to locallhost:8080/images/spider-man-far-from-home.jpg
where 8080 is backend server.

Deploy App to Heroku - I got Internal Server Error

I worked my first application looking at one tutorial for Mongo / Express / Node. App successfully worked on the localhost port:3000 with nodemon server.js.
I connected GitHub directly with Heroku and get message "Internal Server Error" every time.
I would appreciate if someone knows what the problem is. Although the application functioned on the computer, I wanted to learn how to deploy it on Heroku.
require("./models/db");
const express = require("express");
const path = require("path");
const exphbs = require("express-handlebars");
const bodyparser = require("body-parser");
const employeeController = require("./controllers/employeeController");
var app = express();
app.use(
bodyparser.urlencoded({
extended: true
})
);
app.use(bodyparser.json());
app.set("views", path.join(__dirname, "/views/"));
app.engine(
"hbs",
exphbs({
extname: "hbs",
defaultLayout: "mainlayout",
layoutsDir: __dirname + "/views/layouts/"
})
);
app.set("view engine", "hbs");
app.listen(process.env.PORT || 3000, function () {
console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env)
});
app.use("/employee", employeeController);
from your post I can only guess a number of things that could be wrong. Try using heroku logs -t in your terminal (if you have logged in on the heroku cli on your terminal) and comment what you see. It could be that your npm start command is using nodemon (which shouldn't be used for production). It could also be that there is maybe something that isn't in your package.json therefore not being installed on Heroku. If you post what you get on that terminal command I can maybe help you further :)

No content in <app-root> element in browser using the command "node app.js"

I created an Angular 7 application using the Angular CLI. I added my express server as one knows it. Afterwards I used the command "node server/app.js to start my app, but then in the browser in the "Elements" section there appears <app-root></app-root> without any content. As if the browser knew nothing about the actual Angular application. And when I run the ng serve command it seems to know about the actual Angular application, but there appears a 404 not found error in terms of post and get requests to the data server.
I already had a working Angular4 application with -I guess- the same setup and now same things seem to not work any longer.
I researched all day long to find the solution but for nothing.
I think it is not advantageous to post all my files in here. Comment if I was wrong and I am going to edit them.
Thanks in advance.
My app.js:
"use strict";
var bodyParser = require('body-parser');
const cors = require('cors');
// import { Observable } from 'rxjs';
var express = require("express");
var path = require("path");
var app = express();
app.use(cors());
const router = express.Router();
var nodeModulesPath = path.join(__dirname, "..", "node_modules");
app.use("/node_modules", express.static(nodeModulesPath));
var srcPath = path.join(__dirname, "..", "src");
app.use("/src", express.static(srcPath));
var serverPath = path.join(__dirname);
app.use("/server", express.static(serverPath));
// app.use(bodyParser.json());
var models = require("./models");
models.sequelize.sync({force:true}).then(function() {
console.log("TABELLE ERSTELLT");
// app.use(cors());
app.use("/", router);
app.use(bodyParser
.urlencoded({extended:true})
);
app.use(bodyParser.json());
console.log("after bodyparser");
app.get("/", function(req,res){
res.sendFile(path.join(__dirname, "views", "index.html"));
});
// app.get('/*', function(req, res) {
// res.sendFile(path.join(__dirname, "views", "index.html"));
// });
app.post("/goals/create",function (req, res){
models.Goal.create({
id: req.body.id,
name: req.body.name,
content: req.body.content,
firstGivenValue: req.body.firstGivenValue,
fittingValue: req.body.fittingValue,
someone_would_like_to_implement: req.body.someone_would_like_to_implement,
i_know_how_to_implement_it: req.body.i_know_how_to_implement_it
}).then(function(obj){
console.log(obj.id);
// res.end("erfolgreich");
res.redirect("/");
})
console.log(req.body);
});
app.get("/test",(req, res) => {
res.end("test erfolgreich");
});
app.listen(3000);
});
You mention that you think it used to work for angular 4. Currently you're serving the index.html from the src folder. That's not going to work, your app is a typescript app and will need to be compiled one way or another; not to mention the Angular compiler. In the early days (I think pre 4, but not sure) angular serve also write the served files in a folder in your project, so you could just pick those JIT compiled files up and toss them on a web server, or express server. Those days are gone (with good reason for that matter, mostly performance).
You will now have to create an explicit build (ng build) and tell your express server (app.js) to target your dist folder.
TL;DR:
Run ng build
Replace
var srcPath = path.join(__dirname, "..", "src");
app.use("/src", express.static(srcPath));
With:
var distPath = path.join(__dirname, "..", "dist");
app.use("/dist", express.static(distPath));

Using connect-livereload in an Express node app

Following this great article on how to use npm as a build tool, I would like to implement it when building a nodejs express web app.
My node app is created on port 8080, this is a simplified version of my server.js file:
var env = process.env.NODE_ENV
var path = require('path');
var express = require('express');
var logger = require('morgan');
var routes = require('./routes');
var app = express();
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express)
var Oneday = 86400000;
app.use(express.static(__dirname + '/www', {
maxAge: env == 'development' ? 0 : Oneday
}));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, '/public'), {
maxAge: env == 'development' ? 0 : Oneday
}))
if (env == 'development') {
// var liveReloadPort = 9091;
app.use(require('connect-livereload')({
port: 8080
// src: "js/"
// port: liveReloadPort
}));
}
routes.blog(app);
routes.frontend(app, passport);
app.use(function(err, req, res, next) {
console.log(err.stack);
res.status(500).send({
message: err.message
})
});
app.listen(app.get('port'));
console.log('Server starting on port: ' + app.get('port'));
The file that I'm watching before needing to reload is in www/js.
I am using npm as a build tool and before launching server.js with npm I launch a separate process that does watchify source/js/app.js -v -o wwww/js/bundle.js
I did checked that watchify works correctly, updating as I save my files. But there is no livereload once a file is changed.
The error I get in the console is:
Uncaught SyntaxError: Unexpected token <
and I can see that connect-livereload inserted this script in the html:
<script>
//<![CDATA[
document.write('<script src="//' + (location.hostname || 'localhost') + ':8080/livereload.js?snipver=1"><\/script>')
//]]>
</script>
<script src="//localhost:8080/livereload.js?snipver=1"> </script>
I tried also to use live-reload as mentionned in the original article but without success and I am not sure it's the right plugin to use as live-reload launches a server, when I already start one with express.
Any ideas?
connect-livereload only inserts the script into the html (so that you don't need a browser plugin).
you still need a separate livereload server, try node-livereload, grunt-contrib-connect or grunt-contrib-watch ... since you want to use npm as build tool, the first one should be recommendable.
then you would have to change the livereload port to the running live-reload server port (default port is 35729):
app.use(require('connect-livereload')({
port: 35729
}));
The server you tried: live-reload should work as well.
Can you try and start it with:
live-reload [<path>...] --port=35729 --delay=someDelay
and change the connect-livereload option to:
app.use(require('connect-livereload')({
src: "localhost:35729"
}));
This answer shows how to set up livereload to refresh changes to both front and backend files to browser. It might be of help to you. https://stackoverflow.com/a/60542132/5032692

Jade URL Routing in Node Express

I am building a Node Express application using Jade, and I am confused about how to route my views to the specific requests the browser will make. I understand that in order to get URLs to work in the browser, we need to use Node's routes; however, from looking online, I have discovered that Express has its own router.
I used PHPStorm to start up my project, and the index.jade will load... but how do I load the others? Here is my existing code:
var express = require('express'), routes = require('./routes'), http = require('http'), path = require('path');
var app = express();
app.configure(function ()
{
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('less-middleware')({ src:__dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function ()
{
app.use(express.errorHandler());
});
app.get('/', routes.index);
http.createServer(app).listen(app.get('port'), function ()
{
console.log("Express server listening on port " + app.get('port'));
});
What is the most basic way to route my application, and where can I find more extensive documentation on this topic?
Thanks.
I understand that in order to get URLs to work in the browser,
we need to use Node's routes; however, from looking online,
I have discovered that Express has its own router.
Node.js per-se does not provide support for "routes", but Express does. You build your routes in Express using the following syntax:
app.[verb]('[url-path]', [handler]);
So your route app.get('/', routes.index) will process HTTP GET request to URL path / with the routes.index function. Express will automatically pass a request and response objects to your handler.
You can add more routes like this:
app.get('/users', routes.userList);
app.get('/user/:id', routes.userInfoView);
app.post('/user/:id', routes.userInfoSave);
You can find more information about this here http://expressjs.com/api.html#app.param
I am building a Node Express application using Jade, and I
am confused about how to route my views to the specific
requests the browser will make.
Once a route handler is invoked, say (routes.userList) you can call res.render() method inside userList to render the Jade file that you want. For example:
res.render('user_list',
{ users: [{name: "user1", age: 10}, {name: "user2", age: 20}] });
See here for more information: http://expressjs.com/api.html#res.render

Resources