Routing between Express and Angular in MEAN.JS - angularjs

I ran into issues on calling a Express route from my Angular template route and Express -> Angular. This code shows my attempt into tackling this issue.
// Server.js file, the main Node.js code
var Outlook = require('Outlook');
// Bootstrap db connection
var db = mongoose.connect(config.db, function(err) {
etc..
});
// Init the express application
var app = require('./config/express')(db);
app.listen('8443'); // Main server.
// App.js - The Outlook module Express route example code
var app = require('express');
var app = express();
// Configure express
// Set up rendering of static files
app.use(express.static('static'));
// Need JSON body parser for most API responses
app.use(bodyParser.json());
// Set up cookies and sessions to save tokens
app.use(cookieParser());
// Home page
app.get('/', function(req, res) {
res.send(pages.loginPage(authHelper.getAuthUrl()));
});
app.get('/express', function(req, res) {
console.log(req.params.msg);
return 'Your EXPRESS DATA IS HERE!';
});
app.listen(3000); // Is this really necessary?
// outlook.cliet.routes.js
'use strict';
//Setting up route
angular.module('outlook').config(['$stateProvider', '$http',
function($http) {
$http.get('http://localhost:3000/express',{"msg":"hi"}).success(function(data){
console.log(data);
});
]);
Issue 1: I don't want to make express run two different servers in different ports in the same instance. That lead me to next issue.
I am using oauth-sign and simple-oauth2 when I bounce back from the outlook module to the main express server, I am logged off the main server.
I don't think it is required a separate express server. Is it possible to make app.js express routing work without listening to a second express server? Notice that express is initialized in a different way. Perhaps module.exports could help?
Thanks

Related

MEAN application setup doesn't redirect routes to Angular application

I am trying to setup a base for a MEAN application. I created the new project using Angular CLI, added Express.js, MongoDB modules to the application. In the app.js file I have the following configuration:
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
var path = require("path")
var app = express();
var conf = require('./config/conf');
var server = require('http').Server(app);
var mongoDB = require('./adapters/mongodb')
var mongoClient = new mongoDB(conf);
app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,__setXHR_');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
mongoClient.connect(function (dbconn) {
app.dbconn = dbconn;
app.conf = conf;
console.log("************************************************************");
console.log(new Date() + ' | CRUD Server Listening on ' + conf['web']['port']);
console.log("************************************************************");
server.listen(conf['web']['port']);
var Routes = require('./routes/http-routes');
new Routes(app);
});
I setup a hello world route for now and no changes done to the angular sources, which means I would land at the Angular default starting page. But I cant land at the page but instead a white screen page. However, I can access the routes using Postman. I do ng build and then node app.js to run the application. What am I doing wrong?
You should use the Express way to handle routes
First
const router=express.Router();
Then let's suppose you have a file using only authentication routes
const authentication = require('./routes/authentication')(router);
To conclude, you only have to do :
app.use('/authentication', authentication);
This allows a better divison of your routes
You 'll use your routes this way
module.exports= (router)=>{
router.get('/',(req,res)=>{
res.json(message:'Hello World');
});
return router;
To set angular routes you need the router module, for more details read the documentation
You serve only index.html from your Angular App. But you need also serve assets, css and javascript. Easiest would be something like this (but you need to adjust directory names:
app.use('/js', express.static(path.resolve(__dirname, 'dist/js')));
app.use('/css', express.static(path.resolve(__dirname, 'dist/css')));
app.use('/assets', express.static(path.resolve(__dirname, 'dist/assets')));

Post SQL data to Angular View with NodeJS

I'm having a difficult time posting data retrieved from a server using mysql with node. I have connected to my db successfully, and I can return the data I want by console logging it to the CLI when running "node server.js". However, I'm not sure how to post this data to my Angular view. No problem console logging, but this doesn't help me get data to the application.
For the moment, I'm just trying to get the data to index.html, which is my primary view and holds my ng-view portion for Angular routing. I'm probably missing something obvious bc I'm new to NodeJS.
// MODULES
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var mysql = require('mysql');
var serveStatic = require('serve-static');
var bodyParser = require('body-parser');
var source = __dirname + '/public/views/index.html';
app.use(serveStatic(__dirname, {'index': ['index.html']}));
app.route('/*')
.get(function(req, res) {
res.sendFile(source);
});
var data;
var connection = mysql.createConnection({
host : 'thehostdb',
user : 'username', // credentials correct, connection works
password : 'pw',
database : 'db',
port: '3306'
});
connection.query('SELECT * from poemTable', function(err, rows, fields) {
if (!err) {
data = JSON.stringify(rows);
setDataValue(data);
}
else {
console.log('Error while performing Query:', err);
}
});
function setDataValue(value) {
data = value;
console.log(data); //Where the data logs
}
app.listen(port, function () {
console.log('Example app listening on port' + port + '!')
})
You have to understand what this code does, and how nodejs and angular are supposed to work together. Angular is served to the client and then rendered by the clients browser. So if you want to inject data you have to fetch it. So in your angular app when the controller starts make an api call, and in your server create a new route:
app.get('/data', function(req, res, next) {
connection.query(..., function(err, rows, fields) {
res.json(rows);
});
});
Make sure you understand node and it's async nature, what is event loop and how it works and what is callback hell, also I would check out promises and other tutorials on nodeschool.io, it's a great place to start with node :)

How to enable HTML5 mode in Express without breaking NodeMailer?

everyone. I'm making my first Node + Express + Angular app.
I kinda used https://github.com/codeschool/StayingSharpWithAngularSTB as a boiler plate.
The general layout is
[folder] app
--------- [Sub-Folder] Assets (Javascript, css, images etc.)
--------- [Sub-Folder] Pages (This contains ng-view stuff)
--------- [Sub-Folder] Views
-------------------- index.html (This is the main index.html that holds everything together)
[folder] node_modules
[folder] server
--------- [Sub-Folder] Controllers
---------------------- core.server.controller.js
--------- expressConfig.js
--------- routes.js
app.js
package.json
So here's the my server configuring files:
app.js
var app = require("./server/routes");
// Start the server
var port = process.env.PORT || 8000;
app.listen(port, function(){
console.log('Listening on port ' + port);
});
/server/expressConfig.js
var bodyParser = require('body-parser');
module.exports = function(app, express) {
// Serve static assets from the app folder. This enables things like javascript
// and stylesheets to be loaded as expected. You would normally use something like
// nginx for this, but this makes for a simpler demo app to just let express do it.
app.use("/", express.static("app/"));
// Set the view directory, this enables us to use the .render method inside routes
app.set('views', __dirname + '/../app/views');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
};
/server/routes.js
var express = require('express');
var app = express();
var core = require('./controllers/core.server.controller')
// Load Express Configuration
require('./expressConfig')(app, express);
// Root route
app.get('/', function(req, res){
res.sendfile('index.html', {root: app.settings.views});
});
// routes for sending forms
app.route('/contact-form').post(core.sendMail);
app.route('/table-form').post(core.sendTableRes);
app.route('/artist-form').post(core.sendArtistRes);
module.exports = app;
/server/controllers/core.server.controller.js
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: //my gmail,
pass: //my gmail password
}
});
// Send an email when the volunteer form is submitted
exports.sendMail = function (req, res){
var data = req.body;
transporter.sendMail({
from: //my gmail,
to: //another gmail,
subject: data.volunteerName+ ' wants to volunteer for our event 2016',
text: 'Volunteer Info \n Name : '+data.volunteerName+'\n Phone Number : '
+data.volunteerNum+'\n E-mail : ' +data.volunteerEmail
});
res.json(data);
};
// Other similar mailing functions
And here's one of the angular controllers that sends the mail
volunteerFormController.js
angular.module('MyApp').controller('FormController', function($http){
this.volunteer = {
};
this.addVolunteer = function(){
var data = ({
volunteerName : this.volunteer.name,
volunteerEmail : this.volunteer.email,
volunteerNum : this.volunteer.phone
});
$http.post('/contact-form', data).
then(function(response) {
//show thank you message with animate.css classes and hide form
$(".thanksFriend").addClass("animated tada showBlock");
$("form").addClass("flipOutX animated hideBlock");
}, function(response) {
$(".sorryFriend").addClass("animated tada showBlock");
});
};
});
And this works just fine! But if I enable html5 mode in Angular and serve up the index in Express using
app.use(function(req, res){
res.sendfile('index.html', {root: app.settings.views});
});
in the routes.js file, Html 5 mode works great! No 404s when I remove the pound and refresh but then the none of my contact forms work, and the console isn't giving me any errors... My server files are pretty small and it's not super complicated so it should be pretty easy to figure out how to have both HTML5 mode AND working contact forms. Any ideas? I don't know much about Express and I used a tutorial http://www.bossable.com/1910/angularjs-nodemailer-contact-form/ to figure out how to use nodemailer. Is there another way to set up nodemailer so this works?
I would REALLY appreciate some help with this. It's driving me absolutely crazy ;__;
So, you had to serve every request return index.html,
by changing app.get('/', to app.get('/*',

GET error MEAN App

I've been learning how to use the MEAN stack in order to build web apps and so far it's been a lot of fun. Instead of using yeoman generators or npm app to generate my code for me, I've been building my whole app from the ground up. This way I know how each piece connects and what is going on with my app. I was just starting to connect the front and back end of my app when I looked at the developer console and saw
GET http://blog.dev/bower_components/angular/angular.js
Not only angular, but every other resource I have (Modernizr, angular-routes, mootools, restangular, etc ...). When you use the yeoman angular generator you are suppose to run the grunt serve command to start up the angular side. Because I built the app from scratch and I am using npm for my build tool I didn't know how to build the front end server. So, I just went with a simple nginx virtual host pointing to my index.html. Here's the config:
server {
listen 80;
server_name blog.dev;
root /home/michael/Workspace/blog/app;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
I'm not sure what other variables could be affecting the situation, so if I missed something please tell me and I'll be happy to give you what you need!
If you're using the mean stack, you should be able to host both the back end and serve the front end directly with node.
I'm not sure of your project structure but here's the structure for one I'm working on now.
/bin --contains a file called www.js (used to launch app)
/data
/models
/node_modules
/public -- contains my angular implementation
/routes -- contains express routes
/temp
/upload
/views
app.js -- main configuration for express
api.js -- my apis
package.json
in the /bin/www.js file you have the code to start your node server.
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
You'll also need to setup express and your routes so well look at routes first
in the routes directory I have a file called index.js
In this file, I define one route that leads to my angular index.html page.
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.redirect('/pages/index.html');
});
module.exports = router;
And of course you'll need to set up express.
process.env.TMPDIR = 'tmp'; // to avoid the EXDEV rename error, see http://stackoverflow.com/q/21071303/76173
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var multer = require('multer');
var flow = require('./flow-node.js')('tmp');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var uuid = require('uuid');
var mongoose = require('mongoose');
var session = require('express-session');
var routes = require('./routes/index');
var app = express();
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(session({genid: function(req) { return uuid.v4()}, secret: 'XXXXXXXXXXX',
saveUninitialized: true,
resave: true}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
module.exports = app;
Now assuming you have your Angular files and javascript in the 'public' directory somewhere, you should be able to start up Node with the following command.
node bin/www
And the point your browser at http://localhost:3000 and be in business.
Hope this helps and happy learning.

Rendering AngularJS HTML page on server side NodeJS

I have NodeJS server + AnglarJS page.
All works.
Do working examples or frameworks that allow the download page on the server NodeJS and fill it and return to the client a static page. It is necessary for Browsers IE 5-8 (90% clients).
Yes, take a look at Express for Node.js - you can easily serve up a single static page and then use a link to redirect users to your Angular app (using a 'login' page, for example).
Here is an example of a very basic Express app.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
The req (request) and res (response) are the exact same objects that Node provides, so you can invoke req.pipe(), req.on('data', callback) and anything else you would do without Express involved.
The app starts a server and listens on port 3000 for connection. It will respond with "Hello World!" for requests to the homepage. For every other path, it will respond with a 404 Not Found.
Save the code in a file named app.js and run it with the following command.
$ node app.js
Then, load http://localhost:3000/ in a browser to see the output.

Resources