single-page-mean-starter-kit
Bar Talk

Setting Up a MEAN Stack Single Page Application

Beginning an application from scratch can sometimes be the hardest thing to do. Staring at an empty folder and a file with no code in it yet can be a very daunting thing.

In today’s tutorial, we will be looking at the starting setup for a Node.js, AngularJS, MongoDB, and Express application (otherwise known as MEAN). I put those in the wrong order, I know.

This will be a starting point for those that want to learn how to begin a MEAN stack application. Projects like mean.io and meanjs.org are more fully fledged MEAN applications with many great features you’d want for a production project.

You will be able to start from absolute scratch and create a basic application structure that will allow you to build any sort of application you want.

This article has been updated to work with Express 4.0

What We’ll Be Building

A lot of the applications we’ve dealt with so far had a specific function, like our Node and Angular To-Do Single Page Application. We are going to step away from that and just a good old getting started application.

This will be very barebones but hopefully it will help you set up your applications. Let’s just call it a starter kit.

Application Requirements

  • Single Page Application
  • Node.js backend with Express and MongoDB
  • AngularJS frontend
  • Modular Angular components (controllers, services)
  • Good application structure so our app can grow
This tutorial will be more based on application structure and creating a solid foundation for single page MEAN stack applications. For more information on CRUD, authentication, or other topics in MEAN apps we’ll make sure to write other tutorials to fill those gaps.

The Backend Node, MongoDB, Express

Three letters out of the MEAN stack will be handled on the backend, our server. We will create our server, configure our application, and handle application routing.

Tools Required

We will need Node and to make our lives easier, we’ll use bower to pull in all our dependencies.

Bower isn’t really necessary. You could pull in all the files we need yourself (bootstrap, angular, angular-route), but bower just gets them all for you! For more info, read our guide on bower to get a better understanding.

Application Structure

By the end of this tutorial, we will have a basic application structure that will help us develop our Node backend along with our Angular frontend. Here’s what it will look like.



	- app
	----- routes.js
	- config
        ----- db.js 
	- node_modules <!-- created by npm install -->
	- public <!-- all frontend and angular stuff -->
	----- css
	----- js
	---------- controllers <!-- angular controllers -->
	---------- services <!-- angular services -->
	---------- app.js <!-- angular application -->
	---------- appRoutes.js <!-- angular routes -->
	----- img
	----- libs <!-- created by bower install -->
	----- views 
	---------- home.html
	---------- nerd.html
	---------- geek.html
	----- index.html
	- .bowerrc <!-- tells bower where to put files (public/libs) -->
	- bower.json <!-- tells bower which files we need -->
	- package.json <!-- tells npm which packages we need -->
	- server.js <!-- set up our node application -->


We’ll be filling in our files into folder structure. All backend work is done in server.js, app, and config while all the frontend is handled in the public folder.

Starting Our Node Application package.json

All Node applications will start with a package.json file so let’s begin with that.

// package.json
	{
	  "name": "starter-node-angular",
	  "main": "server.js",
	  "dependencies": {
	    "express" : "~4.5.1",
		"mongoose" : "~3.8.0",
		"body-parser" : "~1.4.2",
		"method-override" : "~2.0.2"	    
	  }
	}

That’s it! Now our application will know that we want to use Express and Mongoose.

Note on Express 4 Since Express 4.0, body-parser and method-override are their own modules, which is why we have to include them here. For more information, here’s our guide to Express 4.

Express is a Node.js web application framework that will help us create our application. Mongoose is a MongoDB ORM that will help us communicate with our MongoDB database.

Install Node Modules

To install the dependencies we just setup, just go into your console and type:

npm install

You’ll see your application working to bring in those modules into the node_modules directory that it creates.

Now that we have those, let’s set up our application in server.js.

Setting Up Our Node Application server.js

Since this is our starter kit for a single page MEAN application, we are going to keep this simple. The entire code for the file is here and it is commented for help understanding.

// server.js

// modules =================================================
var express        = require('express');
var app            = express();
var mongoose       = require('mongoose');
var bodyParser     = require('body-parser');
var methodOverride = require('method-override');

// configuration ===========================================
	
// config files
var db = require('./config/db');

var port = process.env.PORT || 8080; // set our port
// mongoose.connect(db.url); // connect to our mongoDB database (uncomment after you enter in your own credentials in config/db.js)

// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json()); // parse application/json 
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded

app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users

// routes ==================================================
require('./app/routes')(app); // configure our routes

// start app ===============================================
app.listen(port);										// startup our app at http://localhost:8080
console.log('Magic happens on port ' + port); 			// shoutout to the user
exports = module.exports = app; 						// expose app


We have pulled in our modules, configure our application for things like database, some express settings, routes, and then started our server.

Let’s look at config and routes since we haven’t created those yet. Those will be the last things that the backend side of our application needs.

Config config/

I know it doesn’t seem like much now since we only are putting the db.js config file here, but this was more for demonstration purposes. In the future, you may want to add more config files and call them in server.js so this is how we will do it.

// config/db.js
	module.exports = {
		url : 'mongodb://localhost/stencil-dev'
	}

Now that this file is defined and we’ve called it in our server.js using var db = require('./config/db');, you can call any items inside of it using db.url.

For getting this to work, you’ll want a local MongoDB database installed or you can just grab a quick one off services like Modulus or Mongolab.

Node Routes app/routes.js

We have created the app folder but there isn’t much in there now. In the future, this is where you’ll want to put things like controllers and models.

Let’s get to our routes. When creating a single page application, you will usually want to separate the functions of the backend application and the frontend application as much as possible.

Separation of Routes

To separate the duties of the separate parts of our application, we will be able to define as many routes as we want for our Node backend. This could include API routes or any other routes of that nature.

We won’t be diving into those since we’re not really handling API or CRUD in this tutorial, but just know that this is where you’d handle those routes.

We’ve commented out the place to put those routes here.

 // app/routes.js

	module.exports = function(app) {

		// server routes ===========================================================
		// handle things like api calls
		// authentication routes

		// sample api route
		app.get('/api/nerds', function(req, res) {
			// use mongoose to get all nerds in the database
			Nerd.find(function(err, nerds) {

				// if there is an error retrieving, send the error. nothing after res.send(err) will execute
				if (err)
					res.send(err);

				res.json(nerds); // return all nerds in JSON format
			});
		});

		// route to handle creating (app.post)
		// route to handle delete (app.delete)

		// frontend routes =========================================================
		// route to handle all angular requests
		app.get('*', function(req, res) {
			res.sendfile('./public/index.html'); // load our public/index.html file
		});

	};


This is where you can handle your API routes. For all other routes, we will the user sent to our frontend application where Angular can handle routing them from there.

Backend Done!

Now that we have everything we need for our server to get setup, let’s create that index.html file so that we can test out our server.

Create an Index View File public/views/index.html

Let’s just open up this file and add some quick text so we can test our server.

 <!-- public/views/index.html -->
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">

	<title>Starter MEAN Single Page Application</title>

</head>
<body>

	we did it!

</body>
</html>

Test Our Server

With all the backend (and a tiny frontend piece) in place, let’s start up our server. Go into your console and type:

node server.js

Now in our console we have:

node-server-start

Now we can go into our browser and see http://localhost:8080 in action.

node-server-hello

So simple, and yet so beautiful. Now let’s get to the frontend single page AngularJS stuff.

The Frontend AngularJS

With all of our backend work in place, we can focus on the frontend. Our Node backend will send any user that visits our application to our index.html file since we’ve defined that in our catch-all route (app.get('*')).

The frontend work will require a few things:

  • Files and libraries brought in by Bower
  • Angular application structure (controllers, services)
  • We will create 3 different pages (Home, Nerds, Geeks)
  • Handle Angular routes using ngRoute so there are no page refreshes
  • Make it pretty with Bootstrap

Bower and Pulling in Components

We will need certain files for our application like bootstrap and of course angular. We will tell bower to grab those components for us.

Bower is a great frontend tool to manager your frontend resources. You just specify the packages you need and it will go grab them for you. Here’s an article on getting started with bower.

First we will need Bower installed on our machine. Just type in npm install -g bower into your console.

After you have done that, you will now have access to bower globally on your system. We will need 2 files to get Bower working for us (.bowerrc and bower.json). We’ll place both of these in the root of our document.

.bowerrc will tell Bower where to place our files. bower.json is similar to package.json and will tell Bower which packages are needed.

 // .bowerrc
{
	"directory": "public/libs"
}

 // bower.json
{
	"name": "starter-node-angular",
	"version": "1.0.0",
	"dependencies": {
		"bootstrap": "latest",
		"font-awesome": "latest",
		"animate.css": "latest",
		"angular": "latest",
		"angular-route": "latest"	
	}
}
	

Let’s run it! In your console, in the root of your application, type:

bower install

You can see bower pull in all the files we needed and now we have them in public/libs!

Now we can get down to business and work on our Angular stuff.

Setting Up Our Angular Application

For our Angular application, we will want:

  • 3 different pages (Home, Nerds, Geeks)
  • A different Angular controller for each
  • A different Angular service for Nerds and Geeks
  • No page refresh when switching pages

Let’s create the files needed for our Angular application. This will be done in public/js. Here is the application structure for our frontend:



	- public 
	----- js
	---------- controllers 
	-------------------- MainCtrl.js
	-------------------- NerdCtrl.js
	-------------------- GeekCtrl.js
	---------- services
	-------------------- GeekService.js
	-------------------- NerdService.js
	---------- app.js 
	---------- appRoutes.js


Once we have created our controllers, services, and routes, we will combine them all and inject these modules into our main app.js file to get everything working together.

Angular Controllers

We won’t go too far in depth here so let’s just show off all three of our controllers and their code.

// public/js/controllers/MainCtrl.js
angular.module('MainCtrl', []).controller('MainController', function($scope) {

	$scope.tagline = 'To the moon and back!';	

});

// public/js/controllers/GeekCtrl.js
angular.module('GeekCtrl', []).controller('GeekController', function($scope) {

	$scope.tagline = 'The square root of life is pi!';	

});

// public/js/controllers/NerdCtrl.js
angular.module('NerdCtrl', []).controller('NerdController', function($scope) {

	$scope.tagline = 'Nothing beats a pocket protector!';

});

Of course in the future you will be doing a lot more with your controllers, but since this is more about application setup, we’ll move onto the services.

Angular Services

This is where you would use $http or $resource to do your API calls to the Node backend from your Angular frontend.

// public/js/services/GeekService.js
angular.module('GeekService', []).factory('Geek', ['$http', function($http) {

	return {
		// call to get all nerds
		get : function() {
			return $http.get('/api/geeks');
		},

		// call to POST and create a new geek
		create : function(geekData) {
			return $http.post('/api/geeks', geekData);
		},

		// call to DELETE a geek
		delete : function(id) {
			return $http.delete('/api/geeks/' + id);
		}
	}
	
}]);

// public/js/services/NerdService.js
angular.module('NerdService', []).factory('Nerd', ['$http', function($http) {

	return {
		// call to get all nerds
		get : function() {
			return $http.get('/api/nerds');
		},

		// call to POST and create a new nerd
		create : function(nerdData) {
			return $http.post('/api/nerds', nerdData);
		},

		// call to DELETE a nerd
		delete : function(id) {
			return $http.delete('/api/nerds/' + id);
		}
	}		

}]);

That’s it for our services. Those are just placeholders and they won’t work unless you define those specific routes in your app/routes.js file. These services will call our Node backend, retrieve data in JSON format, and then we can use it in our Angular controllers.

Angular Routes

Now we will define our Angular routes inside of our public/js/appRoutes.js file.

// public/js/appRoutes.js
	angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

	$routeProvider

		// home page
		.when('/', {
			templateUrl: 'views/home.html',
			controller: 'MainController'
		})

		// nerds page that will use the NerdController
		.when('/nerds', {
			templateUrl: 'views/nerd.html',
			controller: 'NerdController'
		})

		// 
		.when('/geeks', {
			templateUrl: 'views/geek.html',
			controller: 'GeekController'	
		});

	$locationProvider.html5Mode(true);

}]);

Our Angular frontend will use the template file and inject it into the <div ng-view></div> in our index.html file. It will do this without a page refresh which is exactly what we want for a single page application.

For more information on Angular routing and templating, check out our other tutorial: Single Page Apps with AngularJS.

Updated View Files

With all of the Angular routing ready to go, we just need to create the view files and then the smaller template files (home.html, nerd.html, and geek.html) will be injected into our index.html file inside of the <div ng-view></div>.

Notice in our index.html file we are calling the resources we pulled in using bower.

<!-- public/index.html -->
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<base href="/">

	<title>Starter Node and Angular</title>

	<!-- CSS -->
	<link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css">
	<link rel="stylesheet" href="css/style.css"> <!-- custom styles -->

	<!-- JS -->
	<script src="libs/angular/angular.min.js"></script>
	<script src="libs/angular-route/angular-route.min.js"></script>

	<!-- ANGULAR CUSTOM -->
	<script src="js/controllers/MainCtrl.js"></script>
	<script src="js/controllers/NerdCtrl.js"></script>
	<script src="js/services/NerdService.js"></script>
	<script src="js/controllers/GeekCtrl.js"></script>
	<script src="js/services/GeekService.js"></script>
	<script src="js/appRoutes.js"></script>
	<script src="js/app.js"></script>
</head>
<body ng-app="sampleApp" ng-controller="NerdController">
<div class="container">

	<!-- HEADER -->
	<nav class="navbar navbar-inverse">
		<div class="navbar-header">
			<a class="navbar-brand" href="/">Stencil: Node and Angular</a>
		</div>

		<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
		<ul class="nav navbar-nav">
			<li><a href="/nerds">Nerds</a></li>
			<li><a href="/geeks">Geeks</a></li>
		</ul>
	</nav>

	<!-- ANGULAR DYNAMIC CONTENT -->
	<div ng-view></div>

</div>
</body>
</html>

<!-- public/views/home.html -->

<div class="jumbotron text-center">
	<h1>Home Page 4 Life</h1>

	<p>{{ tagline }}</p>
</div>

<!-- public/views/nerd.html -->

<div class="jumbotron text-center">
	<h1>Nerds and Proud</h1>

	<p>{{ tagline }}</p>
</div>

<!-- public/views/geek.html -->

<div class="jumbotron text-center">
	<h1>Geek City</h1>

	<p>{{ tagline }}</p>
</div>

Making It All Work Together

We have defined our resources, controllers, services, and routes and included the files in our index.html. Now let’s make them all work together.

Let’s set up our Angular app to use all of our components. We will use dependency injection and set up our Angular application.

// public/js/app.js
angular.module('sampleApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'NerdCtrl', 'NerdService', 'GeekCtrl', 'GeekService']);

Conclusion

Now we have an application that has a Node.js backend and an AngularJS frontend. We can use this foundation to build any sort of application moving forward. We can add authentication and CRUD functionality to create a good application.

Next Steps

Moving forward, I’d encourage you to take this and see if it fits your needs. The point of this was to have a foundation for starting applications so that we aren’t reinventing the wheel every time we start a new project.

This is a very barebones example and for something more in depth, I’d encourage people to take a look at mean.io for a more in depth starter application.

Check out the Github repo for this project and take from it what you need. Sound off in the comments if you have any questions about how to expand this into your own applications.

Starter Kit

We’ve put this tutorial together as a starter kit at the Github repo. We’ll keep adding features to it on request and any updates we think will be helpful for applications.

Hopefully it will be a good foundation for any sort of Single Page MEAN Stack Application.

To Use the Starter App

  1. Download the code
  2. Install the npm modules: npm install
  3. Install the bower components: bower install
  4. Start the server: node server.js
  5. Visit the application in your browser at http://localhost:8080
  6. Use this starter kit to build any application you need.

Further Reading

When building MEAN stack apps, the backend Node application will usually be an API that we build. This will allow the Angular frontend to consume our API that we built through Angular services. The next step is to hash out building a Node API. This next tutorial will teach us that and then we can go further in depth of how to build the frontend Angular application to consume our new API.

Build a RESTful API Using Node and Express 4

Want More MEAN?

This article is part of our Getting MEAN series. Here are the other articles.

Edit #1 (7/8/14): Updated article for Express 4 support. Thanks to Caio Mariano for the help.

Chris Sevilleja

Design, development, and anything in between that I find interesting.

View My Articles

Stay Connected With Us
hover these for magic

Get valuable tips, articles, and resources straight to your inbox. Every Tuesday.

  • Matt Cowski

    So what are the main differences from this and the previous article? I noticed that here we have: return {
    // call to get all nerds
    get : function() {
    return $http.get(‘/api/geeks’);
    },

    so why do it this way compared to previously?
    $http.get(‘/api/todos’)
    .success(function(data) {
    $scope.todos = data;
    console.log(data);
    })
    .error(function(data) {
    console.log(‘Error: ‘ + data);
    });

    • http://scotch.io/ Chris Sevilleja

      We have separated the HTTP call out of the controller and into a service. This means they are separated. This helps us for many reasons. Moving forward, it is easier to test our code since there is a separation of duties. It is also easier to expand on our service if we need more HTTP calls.

  • Dave

    Hi Chris,

    First of all, thanks for the tutorial. I’ve been following some of your tutorials and I find them really great.
    However, somehow I’m not able to make this tutorial work on my side.
    I’ve followed the instructions and even copy-pasted the code found on github and I’m still getting this exception:

    Uncaught SyntaxError: Unexpected token < jquery.min.js:1:0
    Uncaught SyntaxError: Unexpected token < bootstrap.min.js:1:0
    Uncaught SyntaxError: Unexpected token < angular.min.js:1:0
    Uncaught SyntaxError: Unexpected token < angular-route.min.js:1:0
    Uncaught SyntaxError: Unexpected token < MainCtrl.js:1:0
    Uncaught SyntaxError: Unexpected token < NerdCtrl.js:1:0
    Uncaught SyntaxError: Unexpected token < NerdService.js:1:0
    Uncaught SyntaxError: Unexpected token < GeekCtrl.js:1:0
    Uncaught SyntaxError: Unexpected token < GeekService.js:1:0
    Uncaught SyntaxError: Unexpected token < appRoutes.js:1:0
    Uncaught SyntaxError: Unexpected token < app.js:1:0

    The page is displayed but nothing works, which I believe is because of the above errors.
    Do you have an idea of what is going wrong?

    Thanks,
    Dave

    • http://scotch.io/ Chris Sevilleja

      Hey Dave. Did you run `npm install` and `bower install` to install all the files that were needed? I just pulled down the repo and ran everything and it seems to be working fine.

      Let me know if that works and we’ll troubleshoot further if not.

      • Jean Robert Alves

        hey, thankyou so much!!nbut, i have the same problem.nni’ve already used “npm install” and “bower install”nnbut when i run “node server.js’nnthe page displays alright, but chrome says:nnResource interpreted as Script but transferred with MIME type text/html: “http://localhost:8080/libs/jquery/jquery.min.js”. localhost/:14nUncaught SyntaxError: Unexpected token < :8080/libs/jquery/jquery.min.js:1nUncaught Error: Bootstrap's JavaScript requires jQuerynnnnAnd when I try to upload it to heroku, using git push heroku master,nit says "angular is not defined"nnncan u help me ? thanks

        • Jean Robert Alves

          Hey, just to let you know, i think i found the error.nnin public/index.html u put the wrong path to jquery.min.jsnnnits inside the dist folder hehe nnn^^ thank younn—-nnstill can’t make it run in HEROKU.nnsee here: http://afternoon-citadel-4169.herokuapp.com/nnany help?

          • Jean Robert Alves

            discovered that the directory public/libs was in the gitignore list… don’t know why

          • http://scotch.io/ Chris Sevilleja

            I’ve always taken the approach that node modules and bower components shouldn’t be part of the repo. This helps in that different users can specify different versions before they install if they prefer it.

          • Jean Robert Alves

            hmm, i’m really new in develop ;~nthen if i stay with the .gitignore the way you did it, how my app in heroku will see the files under public/libs? like jquery etc..

          • http://scotch.io/ Chris Sevilleja

            There are a couple different ways you could do it. The easiest way is to fork the repo and change the .gitignore to include the public/libs folder.nnAnother way is to try this method of naving npm install also call the bower command: http://stackoverflow.com/a/18591690/2976743nnnnAlso, another way is to use Grunt JS to automate the installation of npm and bower modules. We’ll be covering that in a future tutorial or there are a few online I’m sure. nnnHopefully one of those helps.

          • Petr

            I had the same issue as some of the above. It appears that the Git repo is missing the “.bowerrc” file. I added that per the tutorial and ran “bower install” again. Now it works!

          • Petr

            ^^disregard^^
            Actually the file is in the Git repo… I realized that I moved the files around in finder and thus .bowerrc didn’t get moved to the working directory. My bad.

          • http://scotch.io/ Chris Sevilleja

            Hello. There was a recent pull request to the repo and I merged it in prematurely.nnnI’ve removed jquery, bootstrap javascript, animate.css, and font-awesome from the repo to make it a simpler starting point. Some people might not use those tools.

  • RIhan pereira

    Hi there Chris,

    very informative and practical tutorial.I liked it.The project structure is neatly organized.One thing I noticed is that you haven’t mentioned about testing SPA’s. how to organize test directories ?since SPA is all about moving business logic and rendering UI using javascript.It is necessary to include TDD along with application development.How exactly do we handle,maintain and organize unit testing directory structure?so the test are reusable and grow progressively.

    • http://scotch.io/ Chris Sevilleja

      TDD is very important and I’m still trying to workout how to best add it to this app structure. I’ll be figuring all that out in the next couple weeks and I’ll add to this app and create a secondary tutorial for it.

      Thanks for reading. For looking at a starting point that has tests built in, mean.io does a good job at that. It can be a bit confusing at first (which is why I created this), but it will definitely help.

      • RIhan pereira

        hi chris,
        ok.For now,I am sticking with current directory structure.what you think about my second question?

        • http://scotch.io/ Chris Sevilleja

          The handheld devices question shouldn’t really make a difference on this overall setup. That sort of responsive design comes with how you develop the frontend.

          Using the Bootstrap 3 grid system will definitely help you to create a responsive design but overall, the concepts stay the same.

  • Mike Kontakis

    Hey Chris! Great Tutorial. Thank you! I would like to ask what is the purpose of services? In your ToDo app you don’t have one. Please explain to me. Thank you.

  • Leard

    Hey Cris!
    Thank you for the tutorial!!
    I’m “newbie” in the MEAN stack, and I have some doubts:
    1- Is this structure good for big applications?
    2- How to config the jade files in the appRoutes.js?

    • Leard

      Sorry…, Chris!!!

      • http://scotch.io/ Chris Sevilleja

        Hello. This is a good foundation for setting up larger apps. If you really wanted to see a fully fledged starter project, take a look at meanjs.org or mean.io. Those are both great help in creating large applications. As a newbie though, they may be a bit harder to see how all the parts work together. That’s why I made this tutorial.

        When using Angular, you don’t want to mix jade and Angular templating. This is why we use HTML and use Angular purely for the front-end data. Angular will request the data using an $http.get from node and then display it, no jade needed.

        • Leard

          Hey Chris,

          Now I’m understand somethings (HTML+ Angular: frontendExpress-Jade:serversideMongo). I’m using mean.io pretty well, your article gave a good start point.

          Thanks,

          Leard

  • jaguilera

    Hi Chris, I was looking for something like that. Many thanks!!!

  • MonsterMe

    U guys are the best !!

    • http://scotch.io/ Chris Sevilleja

      Thanks! You’re pretty awesome yourself!

  • Karen

    Hey Chris! Great tutorial!

    I’m new to the MEAN stack as well (I started out with mean.io) and I feel I might be missing something pretty basic. Is there any way I can push data from Node to Angular?

    I’ve got a SPA and I’m trying to implement search for users from a navigation bar on the header.
    Querying Mongo was easy and returning res.jsonp(users) works fine. However, I would like to send back the data (users) as a parameter for my Angular controller to use.
    All the examples I’ve seen online show Angular controllers/services only pulling data.

    My current solution which I’m not happy with is using Swig to render the user data. I’m not happy with it because I can’t mix in Angular services.

    I saw your comment about not using Jade with Angular and I assume the same goes to Swig. But then how would you implement sending data to Angular?

    Thanks!

    • http://scotch.io/ Chris Sevilleja

      Hey Karen, sorry for the late response. There’s been so many comments lately, this one must have slipped my mind.

      You are correct in sending data using res.jsonp(users). You would send this back to an Angular controller (via $http or $resource). Once Angular has this, it will be able to data-bind the information to the view.

      For a quick example of doing this, see our Node To-Do app.

      http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular

      Hopefully that helps.

      • Jen Looper

        I’d love to get a hand with the CRUD features using this app structure. I have everything working except basic CRUD! Would love some details on where to put the calls.

  • Tuck

    Really appreciate the tutorials Chris! Looking forward to seeing how CRUD is implemented!

    • Jamie

      Seconding this. I’d love to see how CRUD is implemented. I’ve been having a fair number of issues getting it all implemented based on how it was done in the controller/services tutorial. Probably close but something’s not right.

      • http://scotch.io/ Chris Sevilleja

        Definitely next on the list. Going to try to do a bunch of MEAN stack coming up.

  • Pingback: Recent Links – Data, Java, JavaScript, Patterns, MEAN, Cordova, Testing, Node.js | /dev

  • Pingback: ExpressJS 4.0: New Features and Upgrading from 3.0 ♥ Scotch

  • locohost

    Wow, wow, wow, it took a fair bit of searching but I finally found the MEAN project starter that actually makes complete sense. It’s just the stuff we need, not a lot of extra personal preferences thrown it. Thank you, thank you, thank you!!!

    • http://scotch.io/ Chris Sevilleja

      Glad to hear it helped. Those were my exact thoughts. It’s always good to see how to start a project from scratch instead of jumping right into large projects like mean.io or meanjs.org.

      I’ll be extending this article to add on more features so stay tuned for that.

      • Reddy

        Thanks you Chris for this Great Tutorial . You are spot on with SIMPLE tutorial . Even if you extend in future, please keep this as it is and make a NEW project with extensions, so that way people new to NODE and MEAN always have easy time in understanding this EASY project first.

        • http://scotch.io/ Chris Sevilleja

          absolutely we’ll keep this the way it is and keep extending it with extensions. thanks for reading!

  • Pingback: MEAN | Pearltrees

  • Jedi

    Hey Chris, first off fantastic tutorial! Exactly what I needed to start grasping the “beginnings” of things like mean.io

    With that said, I’m having difficulty with the dynamic data/content in this example. Tried myself and a clean git clone.

    When we launch server (node server.js) and then click on the “Nerds” or “Geeks” link, shouldn’t we get Dynamic Content? For instance we have “Geek City” in /public/view/geek.html. From your tutorial it would seem this should be loaded when we click on “Geeks” link, but instead the same page content displays. It DOES change the url to localhost/geeks, just not the content of the page.

    Thanks!

    • http://scotch.io/ Chris Sevilleja

      When running the code, I am able to get dynamic data. Try cloning the repo and see if that works for you.

      https://github.com/scotch-io/starter-node-angular

    • Joseph Myalla

      Hello Jedi, though your concern is two month old, i am facing the same problem no content is displayed when you click nerd or geek link, did you manage to get it working? i need you help

  • Justin

    i tried to just download the code and play with it before going through the tutorial.

    I get the following output:

    $ node server.js
    connect.multipart() will be removed in connect 3.0
    visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives
    connect.limit() will be removed in connect 3.0
    Magic happens on port 8080

    nothing happens when I go to http://localhost:8080/ and the terminal output doesn’t change.

    Any advice?

    • justin

      changed the port to 5000 and it worked . . . mysteries of life . . .

  • the_viking

    Looking forward to your next installments. Please keep up with this series. It has been so helpful for a beginner. Trying to dig into meanjs.org is cool but it is really good to see how things are layered in to build out a large solution like those. Very hard to jump in so late in the process. THANK YOU!

  • SayHi2YourMom4Me

    Pretty new to this, I have a question. it’s simple but long to explain. Anyway, I was following along, except for one thing. In the first part, instead of using an html file to print out “We did it!” like the tutorial did, I used a jade file, and I used res.render(‘index.jade’) in the callback for app.get(‘*’) in the app/routes.js file to render it. It worked great (except I had to put the jade file somewhere different than the public directory for it to render). Anyhow, then I did the rest of the tutorial, and the rest worked great as well. But then I realized one thing. I never updated the routes.js file to tell it to send the public/index.html file. But it was sending it anyway. According to what I know, it should still be rendering the original index.jade file (which I had in a different directory). So naturally I wondered why it was rendering the index.html file. If I go to any other path than specified in public/js/appRoutes.js it renders the jade file, but anyway… my question is, it seems like Angular or bower is overriding the app/routes.js file somewhere to get it to render index.html. Where is this happening and how? Am I missing something obvious? I was messing around and turned off html5mode in the appRoutes.js file on a hunch, and it looks like when I go to localhost:8080 it actually redirects to localhost:8080/#/. Is that what is doing this? Where is this redirect being run? What is html5mode anyway? (actually I can probably google that last one)

    • SayHi2YourMom4Me

      Is it the line in server.js app.use(express.static(__dirname + ‘/public’)); that is sending up the index.html file in the public folder? hmmm. I’m missing a piece of the puzzle here. By the way, testing as the tutorial is written, when I go to the like /nerds it renders, but when I hit refresh it breaks

      • Marco

        in routes.js replace

        app.get(‘*’, function(req, res) {
        res.sendfile(‘./public/views/index.html’); // load our public/views/index.html file
        });

        with:

        app.get(‘*’, function(req, res) {
        res.sendfile(‘./public/index.html’); // load our public/views/index.html file
        });

  • Ognjen Petrovic

    public/js/services/GeekService.js and public/js/services/NerdService.js are (almost) same files.
    For each model we need to add that Service?

    Is there any way to provide basic CRUD methods without *Service.js file?
    I would like to create *service.js file only if I have some methods that are not CRUD

  • http://www.harrythree.com Harry Baldwin

    Thanks for all of the great tutorials! I look forward to more MEAN stuff!

  • aaronchuo

    AWESOME tutorial for learning MEAN !!
    Here’s a tiny bug in app/routes.js

    origin path:
    res.sendfile(‘./public/views/index.html’);

    should be:
    res.sendfile(‘./public/index.html’);

    Thanks a lot !! love all your articles and tutorials. :)

    • http://scotch.io/ Chris Sevilleja

      Sweet thanks. Updated.

  • Pingback: Links da semana #3 | UXDEV

  • Oron Ben Zvi

    Hey Chris,
    Thank you very much for this tutorial!

    Would you suggest going with this one first or the “Node and Angular To-Do App” series?

    Or since you’ve done this tutorial is it deprecating the other one?

    • http://scotch.io/ Chris Sevilleja

      The To-Do series and this are extremely similar. I started the To-Do one before knowing absolute best practices so it’s a good journey from beginning MEAN and then doing good practices as it moves along into the other parts.

      This is more of a getting an understanding of building a foundation for a large MEAN app along the lines of mean.io. I don’t think starting with either one will be bad. They both land on the same concepts and practices.

      • Oron Ben Zvi

        Thanks for your reply,

        just FYI, the good guys of mean.io that were kicked out of there, forked mean.io and created a better repository: http://meanjs.org/ with much better documentation and community support.

        • http://scotch.io/ Chris Sevilleja

          Yes that is a great project and they’ve reached out to us at Scotch to show off their stack. Really cool how they modularize applications. We’re planning on doing tutorials on getting started with meanjs.

  • Vinoth Mahadevan

    why is the starting point NerdController and not MainController?.

  • Pingback: Amazon EC2 + MEAN | Juan Antonio Medina Iglesias

  • Oron Ben Zvi

    Hi Again Chris,

    On “server.js” you wrote:

    exports = module.exports = app;

    exports is actually an alias to module.exports so your first equal sign is actually meaningless, because your code interpreted to something like this:

    module.exports = module.exports = app;

    You have two option to write this line correctly:
    exports = app;
    or
    module.exports = app;

    and again, methodOverride() is irrelevant (:

  • Oron Ben Zvi

    Another bug/inconsistency, the way you wrote the controllers, dependency injection won’t work after minification:

    .controller(‘NerdController’, function($scope) {…}

    but you fixed it on the services using the array technic:

    .factory(‘Geek’, ['$http', function($http) {...}]

  • Oron Ben Zvi

    Just for best practices, scripts should load on the bottom of the page and not in the tag. because loading scripts is synchronous, it’ll stuck the rest of the page to load when it’s on the .

  • Pingback: I need a Hero! – Preferably Scriptman from Planet Java

  • larz

    Nice Tutorial! Thank´s a lot!!!

    One Question:
    In your Index.html you use “” to inject your NerdController to the “body” but this is also in the “appRoutes”!? can i remove the “ng-controller=”NerdController” in the HTML when i declare it in the “appRoutes” ???

    • http://scotch.io/ Chris Sevilleja

      Yes you can change out the main controller in the HTML and then use form controller for the injected. Its good to have an all encompassing controller and then have each injected view have its own controller. This ensures an flexible application.

  • Richard Chu

    is this tutorial updated with Express 4.0?

  • http://www.givenm.co.za/ Given M

    Hey Chris, thanks for taking time out to write this up, really helpful :-) +1

  • Pingback: Angular ng-view not working | Msn4Free.com

  • Pingback: ExpressJS 4.0: New Features - Propellio

  • Teodor Hanev

    How do I send those HTTP requests from the client side ? There is no tutorial for registering a new geek from inputs in the HTML for example. How can I do that ?

  • Raj Yadav

    thanks for your time

  • http://hkajax.wordpress.com/ Hemant Singh

    Awesome MEAN tutorial, Chris you made it so simple, explanation is really great, your explanation about separation of concern (client and server) is just awesome.

    Now I am going to make my hand dirty with your MEAN with grunt tutorial, because I need that badly once we are ready for production.