In this post I’ll go over what the MEAN stack is and how easy it is to setup and develop with. Hopefully this will give you enough of a taste to try it yourself. The post will cover the following topics :
What is MEAN.IO
Hello, World! in MEAN.IO
Developing with the MEAN.IO stack
What is MEAN.IO
Let’s take a quick look at each technology and why it’s in the stack. Although the order above forms a nice acronym, we’ll address them in a conceptually more appropriate order:
AngularJS is the front end, UI and client side logic of the stack. The application’s structure is defined in HTML and extended by AngularJS directives. Control logic is nicely separated into Controllers which are easy to re-use and organize. Angular brings a lot to bear in reducing complexity but at the cost of less control. more info
Git (version control) download
MongoDB download. MongoDB can be tricky to setup. On Debian, it’s simply an apt-get but on Windows it requires download and installation, followed by running the MongoDB service. MongoDB’s guide covers these variations in detail. You can also skip this and create a remote database on MongoLab. Just update the MongoDB URL in
Bower - a package manager, more info.
- Grunt - a build tool, more info.
Creating a MEAN.IO project
Okay, so you’ve run some commands from a blog, what has it done? If you check the command line output you’ll notice that
$ mean init created a default project, with structure, code and config, by cloning a git repo. The project’s external dependencies were then installed using
$ npm install. Inside the new project you’ll find the following folders.
bower : The bower folder contains some of the front end libraries that are used. These are angular, a few default angular modules, bootstrap and jquery. Bower is handled by our build file that we’ll introduce later.
config : This contains our Express config, our list of bower assets and an
envfolder contains configuration files for each stage, production, development and test. This means we can use different URLs, logins and database config when building the project.
node_modules : This folder contains more external libraries that are needed or helpful. There’s too many to go through but I’d recommend checking out passport the authentication module and mongoose, the node-to-mongoDB database connector.
packages : Mean provides more structure by dividing features out into packages. These are found under the packages folder. This is where you’ll add your code when you start to develop the stack. You’ll notice there’s already some features provided by MEAN.IO’s project scaffolding. * access - authentication handling code, for intercepting requests, routing them to an auth provider and handling the callback. * articles - the default CRUD functionality. Great for understanding the data flow and basic web application structure. * contrib - awesome admin control for your application. Allows an admin to update config, themes and database from the front end UI * system - logic and ui for the index page and navigation header * users - out of the box user management, handles forgotten passwords, sign up, login and the usual boilerplate.
INSIDE A MEAN.IO PACKAGE
app.js Contains the feature’s meta config, such as menu items.
public (the front end) - assets - CSS and images go here - controllers - the front end processing - routes - routes to each view - services - angular wrappers for data providers - tests - karma tests - views - the HTML for each page
server (the back end) - controllers - the back end processing - models - the data object’s definitions - routes - routes to the controllers, from get/posts… - tests
Hello, World! In MEAN.IO
With all this default structure and code, where do we jump in and start coding? Let’s be original and create a website that displays ‘Hello World’.
Open the file
packages\system\public\views, this is the HTML description of the index page. We’re navigating into
system as it handles the front page and menu navigation. We’re going into
public as it holds the front end logic and UI. We’re going into
view as that’s where the pages are defined in HTML. Grab all the stuff inside the
<section> element and delete it. Then type
Hello, World!. It should look like:
Now, we’ll build and run the application. You’ll find the build file, Gruntfile.js, at the top level of the project. Run grunt and go to http://localhost:3000 to see it in action
Wait what just happened? Let’s take a look in the build tool’s configuration file. We can see the tasks registered at the bottom with each of their steps listed. Running grunt without a parameter actually calls
You’ll also notice the environment variable,
NODE_ENV, which can be set or checked by grunt to use different build tasks, config and even databases.
If you got lost or stuck take a look at the official MEAN.IO guide to installation for full details. It’s worth taking a look around the site at this point and see how the example CRUD feature, articles, works.
Developing the mean stack
The default app involves creating articles which only members can see. It also shows every article to every user. Let’s add some extra functionality to the default app that shows us the structure of the stack. Here’s our token user story to rectify that.
As a user, I would like to be able to publish the best articles for public consumption.
This breaks down into the following tasks : 1. list all articles on the front page 2. add a filter to the front page to only display published articles 3. add a ‘published’ state to the article model 4. add a mechanism and UI to change the published state of an article 5. make the articles private to a user if not published 6. update the sites styling 7. deploy the application
1. list all articles on the front page
We’ll clean out the MEAN.IO propaganda from the front page by copying the contents of
packages/system/public/view/index.html. The code we just ‘borrowed’ is a view which lists articles. It contains some article data and two buttons for modifying the article. Make sure to remove the
H1 element at the bottom for creating new articles as we don’t want that behaviour on the front page.
2. add a filter to the front page
Now we restrict the articles on the front page to those that are published. Go to the html file for the front page,
packages/system/public/views/index.html and change the element
ng-repeat is an Angular directive that uses the tagged element and it’s children as a template for displaying each article in the list called articles. A list comprehension is added that filters out articles that don’t have a ‘published’ field equal to ‘true’.
3. add a ‘published’ state to the article model
The front page will be empty now as all of the articles will be filtered out. Let’s add a
published field to the article model in the database.
find the file
packages/articles/server/models/articles.js and add the following to the existing properties
This really highlights why we’re using MongoDB, using JSON to specify the model is simple and easy to understand.
4. add a way to change the published state of an article
Articles are now not published by default so we need a mechanism to edit the state. Let’s add a button to each article that toggles its published state. Go to
packages/system/public/view/index.html and add the following button
You’ll notice it looks like the other buttons but calls a different function.
glyphicon is a CSS class used to add an image to the button; it’s included as part of bootstrap. We now need to add the function to the controller. Go to the ArticlesController, located at
packages/articles/public/controller/articles.js and add the following :
Now the button can be clicked on each article to change its published state. If you take a look around the controller a bit more you’ll see the update, remove and add functionality. The publish functionality is just a mix of existing CRUD functionality. With this we can publish articles to the front page and view them without logging in. However, If we add a new user we notice that the first user’s articles are appearing under the private article list.
5. making the user’s articles private
packages/articles/app.js and change the title from ‘Articles’ to ‘My Articles’. This updates the button in the menu and makes it clear to the user that their articles are private. We’d like to restrict the listed articles on that page to those that belong to the current user. If we look in the ArticlesController, we can see the reference to the current user in the
hasAuthorization() function. We’ll create a synonym for the current user into the ArticlesController to keep it clean.
We’re currently using the same controller for both the front page and private page. The data is loaded using the
find() function in ArticleController. Let’s load different data for the private page.
find() function in ArticleController to
This means that if a user is provided, the function should remove articles that do not belong to that user. Go to
packages/articles/public/views/list.html. Update the call to find by providing the currentUser we just placed in scope.
6. update the styling
Now that we have some new functionality, let’s be a real full stack developer and update the UI. Bootstrap comes with MEAN.IO so let’s override the default values and make the heading a bright colour. You’ll find the index page’s CSS in
packages/system/public/assets/css/common.css. Just add the following and use your favourite colour as the heading background
At this point, it would be nice to have some admin control. Luckily, this is provided out of the box by MEAN.IO. Simply update a user in the mongo database by adding a role, “admin”. This allows that user to manage the app, its settings, change the theme dynamically for all users, add and edit other users. Also, the admin is authorized to edit, remove and publish/unpublish any article. Check the
hasAuthorization() function in ArticleController to see why.
7. Deploying the application
Now that we have a minimal viable product, you can deploy it. MEAN.IO leans towards heroku, a cloud platform for running applications, but anything node-based should work. For this blog post I’ve developed and deployed the example using cloud 9 another cloud based service that provides a browser IDE and linux kernel.
Database hosting such as mongolabs is free. You can update the database’s URL and other settings in
This blog demonstrated how to change * front end logic * front end ui * data model * styling
It should have also given you a taste of Angular.
In the end, MEAN.IO is just a tool. If you require a fast, easy, simple way to create a modern, responsive, dynamic web site then MEAN.IO would be a great solution. If you’ve followed the steps this far, creating your responsive website only requires a quick
mean init ...