Images uploaded with Node server cannot be found by Angular 2 - node.js

I have an app in Angular 2, decided to add real server, Node JS, to upload documents and do other things.
Browser => Angular [localhost:4200/api/documents] => Node [localhost:3000/documents]
This is how I start them together using scripts in package.json
"scripts": {
"server-start": "gulp",
"client-start": "ng serve --verbose --proxy-config server.conf.json",
"start": "npm-run-all -p client-start server-start"
}
So, when I run npm start it starts 2 parallel processes - Node JS using Gulp and Angular using ng serve. Angular is a front end, but all URLs that start with /api get redirected to Node. Here is how it's done with server.config.js
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
Node JS receives stream from Angular with image and saves it in Angular assets folder, so uploaded image should be available in Angular, but when I try to open uploaded image in browser it returns me 404, not found. Just in case, this is part of my .angular-cli.json
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico",
"service-worker.js"
],
"index": "index.html",
"main": "main.ts"
Example, I have existing image that was there before ng serve
F:\Node\cms\src\assets\uploads\1.jpg
available at, it works
http://localhost:4200/assets/uploads/1.jpg
I upload new one to the same location
F:\Node\cms\src\assets\uploads\5.jpg
but it's NOT available at
http://localhost:4200/assets/uploads/5.jpg
When I restart my servers image becomes available. According to this discussion ng serve performs deployment of Angular app in the background, and folder dist is empty, all images are taken from memory, and any new images dropped into assets won't be available, correct me if I am wronng.
Question #1: is built-in Angular server able to handle dynamic images if they were added when application is already running in memory?
Question #2: looks like in complex apps ng serve brings more troubles than benefits, is it worth to try to make it working or you'd recommend to start using ng build instead?

when running your application, everything points to build folder. Not "src"
You probably are wiping out the images each time you run my serve or need to store them in a different location.
You are technically storing images on a "server" so I recommend using node to retrieve the paths to these files.

You should use ng build instead of ng serve. ng serve is meant for dev purposes. See https://github.com/angular/angular-cli/wiki/serve
Additionally after running ng build you will need to have the dist folder on an actual server. Here's an example from the Angular wiki
https://github.com/angular/angular-cli/wiki/stories-disk-serve
ng build --watch
lite-server --baseDir="dist"
You could also have node serving the dist folder using the static method that is built into node.
The line to add would be either
app.use(express.static('dist'))
or
app.use(express.static(path.join(__dirname, 'dist')))
See https://expressjs.com/en/starter/static-files.html
I prefer to do ng build -aot to get the bundle size as small as possible and then serve the dist folder with nginx.

Related

How to setup and run ionic app and node express api within one application?

I have two separate applications one is the ionic app and other is node express api app. Is it possible to merge both in one application? Like for example when i enter npm run start it should run ionic serve and node index js both?
Typically after you finish developing your frontend you "build" it. This minifies and optimizes frontend files. For ionic: https://ionicframework.com/docs/cli/commands/build
This creates a folder(the default name can be "dist" or "build" etc). You put this folder in your backend folder, then serve it statically. For static serving check out https://expressjs.com/en/starter/static-files.html.
This way you deploy only backend, and it works. You can make api endpoint routes start with "/api" and "/" routes can be for frontend's static serving.
If you mean you want to do that for development purposes only, you can use concurrently command https://www.npmjs.com/package/concurrently
npm install -g concurrently
After installation, add this line to package.json script
"start": "concurrently \"command1 arg\" \"command2 arg\""
In command1: add ionic start command, like: ionic start
In command2: add node start command, like: nodemon server.js

Deploying an Angular App in Node JS (express) server through http-server

I'm trying to put an angular application in "production" on a local server that is generated by the http-server tool, but it does not return the of the index.html.
I followed these steps ...
ng build --prod (this throws me the project folder for production like this -> "dist / project-erp")
http-server
web server
Update:
So, I changed the base route to "/" but still happening in same situation :/
After many tests of building the project, the solution to launch it on the Express server (it worked for now) is to just do the command "ng build" instead of "ng build --prod", then the folders "dist / project-erp "put them on the backend server.

Serving Node Server and Angular 4 application in one command

I am starting a new project which is using Angular 4 for frontend designing and the application will need some rest api's for which I have decided to use node. I am using angular cli for creating angular app and I know how to create angular app and node server but I want to know how will I connect these two things such that when I do ng serve both the server and angular app gets compiled and run. What basic changes in the project structure or some file is needed to be done?
I'm currently building a full-stack Angular app with a Node/Express backend and was wondering the exact same thing. However, despite what that scotch.io tutorial tells you, creating both the Express server and the Angular app in the same directory is NOT the best way to go about it.
What you want to do is set up your Express server in one project and serve it in one terminal window, then serve your Angular app in a separate terminal window but have it point to your locally-running Express server instead of the default dev server that's included with the Angular CLI (the ng-serve command).
Here's a Stack Overflow answer and also a Medium article that answered all of my questions for how to set this up (fortunately, it's not too hard).
Here's what I did Shubham. I went into the Angular-Cli and changed "outDir": to "../public"in other words it will look like "outDir": "../public". The ../public folder is my Express static folder set in my app.js file with app.use(express.static(path.join(__dirname, 'public')));
Keeping in mind I have nodemon installed globally, and in my package.json file, "start": "node app" I simply run nodemon from this dir to start my server and both Angular and Express run on the same server.
I have seen some people say it's not good to run static filed on the Node/Express server, but for development I'm not sure it matters. Although I'm a novice when it comes to js frameworks etc. Here's the project files on my github acct: https://github.com/chriskavanagh/angularauth.
Edit: You must run ng-build (in your Angular dir) whenever you change code.
First, in Angular project do ng build, it will create dist folder (static folder).
Second step, paste the following code in backend servers entry point file.
app.use(express.static(path.join(__dirname, 'dist/')));
app.get('*', (req, res) =>{
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
And after the above thing is done run backend server: node filename
Note: in give proper path where your index.html file is located in dist folder.
The node server and the Angular app are two different things.
In order to run the node server you should use the command:
node ServerName.js
In order to run the angular app you should use the command:
npm start OR ng serve
In your case, the connection between the two is made by http requests.
For example you could use 'express' in order to implement rest services in your node server and then send an http request to the server in the current route.

How to add angular 4 to existing node.js application

I have a node.js application set up to use typescript.
The application is supposed to be deployed on heroku.
The node.js application is set up as an restful api for things like auth, registration and requests.
I would like to know what dependencies I need to add in order to begin building an angular 4 application in the same project.
I saw an issue on github where the recommendation was to use ng init however that is no longer an option. ng new creates an entirely new project directory rather than adding the dependencies and files.
There is another question on here where the OP marked his own answer as correct which basically says "use meteor".
EDIT:
I understand how to serve an angular 2+ application along side from within a node.js app when working locally, just build and serve the index.ts file. But how can I have the angular development files coexist with node.js files in git so I can compile them and deploy them together?
I had the same case, I had a parse server on heroku and wanted to group it with Angular.
In my server.js file :
app.use(express.static(__dirname + '/dist'));
(You just need express)
I also use internationalization, so I made something quick (early stage, please don't judge) :
app.get('/', function(req, res) {
let userLanguage = req.headers["accept-language"];
let langs = ['fr', 'en'];
let preferred = userLanguage.substr(0, 2).toLowerCase();
console.log('User\'s preferred language is ' + preferred.toUpperCase());
if (langs.indexOf(preferred) >= 0) { res.redirect(preferred); } else { res.redirect('/en'); }
});
My NG commands :
"postinstall": "npm run build-i18n",
"i18n": "ng xi18n --output-path src/i18n --out-file messages.xlf",
"build-i18n:fr": "ng build --output-path=dist/fr --aot --prod --bh /fr/ --i18n-file=src/i18n/messages.fr.xlf --i18n-format=xlf --locale=fr",
"build-i18n:en": "ng build --output-path=dist/en --aot --prod --bh /en/ --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf --locale=en",
"build-i18n": "npm run build-i18n:en && npm run build-i18n:fr"
My apps is built in 2 folders for the actual 2 languages, and the user is redirected to either of them when he comes to the app.

Deploy the backend and frontend on the same Heroku app/dyno

At the root of my project, I have a frontend and backend folder. Both folders contain a package.json that list their dependencies. How do I tell Heroku to run npm install on both folders when deploying the application? It seems like Heroku expects to have a single package.json file by default. Do I have to do something with a Procfile? The Heroku documentation doesn't seem to tell much about my specific question.
Thanks for the help!
I just successfully completed this goal using static files created during a heroku postbuild step, as described in this blogpost. I have a React frontend (could be anything though) and Express API backend. Each process has its own port in dev, but deploying on Heroku uses just one total.
Put the working frontend in a subdirectory of root (such as /frontend).
Put the working backend in a subdirectory of root (such as /api -- the blogpost assumes the backend remains in the root directory -- either way is fine).
Proxy API requests from the frontend to the backend by adding this line to /frontend/package.json (replacing 5000 with your backend port):
"proxy": "http://localhost:5000",
Add the following to api/app.js (or api/index.js) in the backend (be sure the last part is AFTER you define the appropriate backend [or api] paths):
const path = require('path')
// Serve static files from the React frontend app
app.use(express.static(path.join(__dirname, '../frontend/build')))
// AFTER defining routes: Anything that doesn't match what's above, send back index.html; (the beginning slash ('/') in the string is important!)
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/../frontend/build/index.html'))
})
Edit the root directory's /package.json file with something like the following (note that using the concurrently package allows an easy way to run the whole app locally with npm run dev, but only heroku-postbuild is required here):
"scripts": {
"frontend": "cd frontend && npm start",
"api": "cd api && nodemon app.js",
"dev": "concurrently --kill-others-on-fail \"npm run api\" \"npm run frontend\"",
"heroku-postbuild": "cd frontend && npm install && npm run build"
},
Make sure you install all backend package dependencies in the root directory, or you will get errors.
Make sure your /Procfile has something like web: node api/app.js
Seems that you can put a package.json file on the root of the project and use scripts to invoke npm i in both folder.
https://devcenter.heroku.com/articles/nodejs-support#customizing-the-build-process
Something like cd front && npm i && cd ../back && npm i
But i should say that if they are running on different ports, it may not work as it seems that only one web process per procfile is available.
this last point is to confirm.
You can define several entry points for your project in the Procfile :
web: cd front && npm i && npm start
server: cd backend && npm i && npm start
However, you have to upgrade to Hobby at least. It's 7$/dyno/month.

Resources