Creating Apps with Angular and Node using Yeoman

Yeoman generators can save you a huge amount of time writing boilerplate, and give you a great foundation for building apps. Today we’ll be looking at a workflow for making applications with an Angular, Express, and Node stack using the Yeoman angular-fullstack generator.

You’ll need to have Yeoman installed, and the angular-fullstack generator, which can be installed using npm install -g generator-angular-fullstack

Scaffolding an app

Create a new empty folder to work from

mkdir newProject

cd newProject

Now run yo angular-fullstack to scaffold out a new client and server application, and download all the dependencies.

Alternatively, if you prefer using jade templates over html you can alternatively use yo angular-fullstack --jade

You will get several questions asking how you would like to configure the app, such as if you want to include a mongoDB connection. For now we’ll just use the defaults.

yo angular-fullstack

Starting the application

When that’s done, start the serve task:

grunt serve

This starts the express server, and opens the newly scaffolded application from a browser.

This also starts the livereload task, so any changes you make to the client files get automatically reloaded, and any changes you make to the server files automatically restart the server.

Creating your application

Before we begin, lets have a look at folder structure we’ll be using.

  • app -> Development folder for client views, scripts, and assets
  • test -> Tests for your client code
  • lib -> Your server application logic 
  • server.js -> Initializes express server, server configuration

Lets try a trivial example to get familiar with editing the project. We’ll get a message of the day from the server api and display it in our app.

Server modification

Create a function to handle message requests.

// lib/controllers/api.js
...

exports.message = function(req, res) {
  res.send('Hello World');
};

Add in a new route

// lib/routes.js
...

// Server Routes
app.get('/api/message', api.message);

Now if you navigate in your browser to http://localhost:9000/api/message you should see the server respond with Hello World.

Client modification

Ok, so now you have a basic server api you can access, lets hook it up to our client so we can display it in a view. We’ll make a new AngularJS route for this. From another command prompt, CD into your working directory and run:

yo angular-fullstack:route message

In the newly created Message controller, lets make an $http get request to our new api route and bind the result to our scope.

// apps/scripts/controllers/message.js
...

  .controller('MessageCtrl', function ($scope, $http) {
    $http.get('/api/message').success(function(message) {
      $scope.message = message;
    });
  });

Now navigate to the view that was also created by the generator, and bind the message to our view.

// app/views/partials/message.html
...
The message of the day is {{ message }}

Navigate to http://localhost:9000/message to see the new view, which now will be displaying the message from the server. It’s as simple as that.

Build for production

Next we’ll cover how to build the app for production so your assets and scripts are optimized for a live server.

grunt build

This grunt task minifies scripts, css, compresses images files, and updates all the references in your views to point to the new minified assets. Packages everything up for you and outputs the result to:

  • dist

We can also launch the production build locally using:

grunt serve:dist

Which does the same build process as grunt build, but launches the final application so you can see it in action.

Deploy to heroku

This step requires you to have the heroku toolbelt installed.

Initializing heroku folder

Use yo angular-fullstack:deploy heroku

This will do a grunt build, copy all the production files into the dist folder, create a Procfile required by heroku, and initialize a git repository for you.

Finally, it will create a heroku app for you, with the heroku toolbelt, and sets the node_env to production.

Push to heroku

Once it’s all done with that, you’ll need to git push the dist folder to deploy it.

cd dist

git push heroku master

When you’re done uploading, you’ll be able to open the newly deployed application with

heroku open

Making changes and deploying again

If you make additional changes to the project that you’d like to push to heroku, from the project root use the following command.

grunt build

This will build the new version of the app and copy it into the dist folder. You’ll need to use git to add any new files, and commit your changes to the heroku folder. And then push your new changes to heroku with.

git push heroku master

Final note on testing

One thing I didn’t really go into was testing, but it should be an important part of your work flow as well. Use grunt test to run through your unit tests. I hope to integrate server tests with mocha in a future release of angular-fullstack.

In conclusion

Hopefully, you now have a more robust work flow for developing, testing, and deploying full stack applications. If you’d like to learn more about this generator, head over to the github page to read more. I plan on making more advanced guides to demonstrate new features as they’re added to angular-fullstack. Have fun making cool apps!

Share Button
  • jeffprandall

    After the Client Modification I had to add a route ‘app.get(‘/message’, api.message);’ in server.js to get localhost:9000/message to load.

    • tylerhenkel

      You don’t want ‘/message’ to point to the api.message, we want ‘/message’ to actually display our view.

      Did you generate an angular route for ‘message’ using `yo angular-fullstack:route message`?

      We should have two distinct sets of routes, those for api endpoint on the server, e.g. ‘/api/message/’, and those for the client routes that angular uses, e.g. ‘/message’.

      Client routes such as ‘/message’ should automatically work if the angular route was properly set up.

      • jeffprandall

        I did run yo angular-fullstack: route message and it created the controller and view but it didn’t tweak my server.js. Under the Angular routes section all I have is –

        app.get(‘/partials/*’, controllers.partials);
        app.get(‘/*’, controllers.index);

        • tylerhenkel

          That’s correct. No new routes need to be added to the server for them to work for Angular, they are added to the angularjs routing system, located in app/scripts/app.js, when you run that generator. That’s the only route you need added for the view to work.

          The way this works is that all non declared routes that the user tries to visit are redirected to index.html. This makes it so your angularjs application is always handling routes unless they’re specifically declared by the server.

  • dkruger

    Great Article!!!

  • Todd Linnertz

    Great article and tool!

    • tylerhenkel

      Thanks for reading!

  • yolo

    What should i do if i want to user coffeescript?

    • tylerhenkel

      Just run yo angular-fullstack –coffee

  • Patrick Cauley

    Do you plan to write a tutorial on the Anuglar Passport app you created as well? I’m reading through the code trying to do something similar but learn along the way.

    • tylerhenkel

      Sure, I’ve actually been meaning to work on that. I’ll try to write something soon. It’ll probably have to be a multi-part blog, because there’s a lot I’d want to get to, server authentication, client-side and server side validation, and making a rest endpoint for mongodb, among other things.

      • Patrick Cauley

        That’s awesome. I’m a front end dev who has been using Angular for a relatively small amount of time, I’ve played around with Rails and made a simple blog with it and I wanted to try a MEAN stack but wow is it difficult in comparison. However I think that’s a lot due to the tutorial I found for Rails was really great and I haven’t found any really encompassing MEAN tutorials.

        I seem to run across a lot of “Here is how you set up this one tiny part of an App”, then when I try to integrate it with others everything breaks.

        I’m using your Yo-Angular Fullstack generator and trying to integrate it with Passport, off the top of your head is there anything wildly different from your Angular Passport app to the generator that I should be aware of?

        • tylerhenkel

          I have heard that Rails is easier to use than Node/Express, but I haven’t had much experience with it. If you still have the link for that tutorial, I’d like to get a better idea of how it works.

          There shouldn’t be any major differences between the project structures for angular-passport and what the fullstack generator scaffolds, I used the generator to scaffold out the start of the project.

          • Patrick Cauley

            http://ruby.railstutorial.org/chapters/beginning#top

            I’ve heard it’s basically the best Rails tutorial out there. I know I had a blog set up using it within a few hours and at least a basic understanding of Ruby/Rails.

            I set out to create a MEAN blog because it’s definitely the buzzword as of now, not to mention I thought my previous knowledge of Javascript would help out lol. Not sure how much it has.

            Awesome, good to hear there shouldn’t be any major differences.

          • tylerhenkel

            Sweet, thanks. I’ll check it out.

            Oh btw, I’ll probably hold off on writing on the part about setting up passport until it’s incorporated into the generator. Kjellski has been working on a pull request that adds a passport question to the generator, and I’m going to try to help him get that finished so we can add it in the next release.

            Ideally I’d like to have a lot of the server side stuff in angular-passport automated by the generator. Being able to add in a rest end point with CRUD capabilities would be a perfect use of a sub-generator.

          • Patrick Cauley

            That’s fine, I’m trying to read through the app now and understand it hopefully well enough to get it working by the end of the week. Do you have any good resources on learning ME-N part of MEAN? I feel as if I let the generator do far too much for me. I understand Angular really well but the back end stuff throws me for a bit of a loop.

          • tylerhenkel

            This is probably the best one I’ve seen http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular.

            I haven’t seen a lot of good MEAN tutorials though. I would suggest reading into validation with mongoose though, since it’s a really important part of using mongo.

          • Patrick Cauley

            Yepp! I’ve been following Scotch.io and they generally have great tutorials however they suffer from the same issue of bringing it all together. I should probably create an Express blog and then add the Angular part on afterwards instead of trying to do it all at once as I have been trying.

          • tylerhenkel

            That’s probably a good idea. Just focus on making a solid API for your blog, and then figure out how to hook it up to a frontend later.

          • Patrick Cauley

            You’re awesome thanks for all of the help!

          • tylerhenkel

            Good luck! :)

          • Patrick Cauley

            I modeled my application after your Angular-Passport app, by modeled I mean typed it up exactly more or less for now. I am getting a 500 error when registering a user. My terminal is giving me an error:

            node-crypto : Unknown message digest shal

            Error: hmac error

            at new Hmac (crypto.js:226:17)

            at Object.Hmac (crypto.js:224:12)

            at model.UserSchema.methods.encryptPassword (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/lib/models/user.js:91:17)

            at model.UserSchema.virtual.get._id (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/lib/models/user.js:31:30)

            at VirtualType.applySetters (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/virtualtype.js:94:25)

            at model.Document.set (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/document.js:450:12)

            at model.Document.set (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/document.js:421:18)

            at model.Document (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/document.js:66:17)

            at model.Model (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/model.js:34:12)

            at new model (/Users/patrickcauley/Dropbox/Work/Personal Projects/meanBlog/node_modules/mongoose/lib/model.js:1755:11)

            POST /auth/users 500 4ms – 1.11kb

            Do you know what might cause that error? Is it due to running locally, something I set up badly, like mongo, or possibly a typo? If it’s a typo I can find it myself, I just thought it might be that I set up Mongo wrong.

          • tylerhenkel

            Cool, glad you got it working. If you do have any more issues with crypto, you might want to switch to bcrypt, or if you really want to make it secure. I used crypto in that app, but I’ve learned that for bcrypt is the way to go for passwords, just check out this article http://codahale.com/how-to-safely-store-a-password/

          • Patrick Cauley

            Couple of quick questions on your passport blog app, in your factory for blog, why do you only create an “update” resource and not a create?

            I am getting a 500 error on adding posts however I know the database is working because I manually added some. I’ve done it with a fresh database and with some manually entered entries and both times I get the 500 error. I’m not sure what to be looking for as far as fixing it goes.

            I console logged the blog object and it seems to be the correct title and content.

          • tylerhenkel

            $resource has some built in methods for saving, deleting, and getting from the specified url, so there’s no need to make a create method. However, it does not by default have a put method for updating a resource, so that’s why I added one.

            I wish i could help with the blog error, but I don’t think I can give you any advice without some more specific error messages or looking at the code.

          • Patrick Cauley

            I could put it on github however thats way too much work and you’ve already been a huge help! I think it has to do with the back end. I think I am going to make my own model and controller with node and express for the blogs.

            Do you have resources on the exports.VAR that you used? I googled around and found it’s a node thing however I don’t know why it’s separated out like you have it. I was using this Modulus blog post however they have it set up differently than you do.

            http://blog.modulus.io/getting-started-with-mongoose

            I owe you a coffee or something because you’ve been super helpful!

          • tylerhenkel

            This is a pretty helpful answer explaining node modules: http://stackoverflow.com/questions/5311334/what-is-the-purpose-of-nodejs-module-exports-and-how-do-you-use-it

            The basic run down is that exports allow you to specify the public api for a module.

          • http://scotch.io/ Chris Sevilleja

            Hey guys. Great read on Angular and Node. I write those articles for Scotch.

            @disqus_454q2CCFJ4:disqus if you could provide some feedback, I’d love to hear where we could make our articles easier to read.

            @tylerhenkel:disqus it’d be great to see that Angular/Passport series. I just finished up a Node/Passport one but Angular would be an awesome read.

          • Patrick Cauley

            Hey Chris, I don’t know if I have any constructive feedback, generally your tutorials on Scotch are fantastic. To be honest, I am just asking for way more than can be expected of anyone. Really what I want is a tutorial similar to Hartls Rails tutorial but for a MEAN stack. That is way more than can be expected of anyone.

            My only request might be a tutorial with an Angular front end,and an Express back end however I believe you’ve already said you plan on creating that.

          • tylerhenkel

            Hey Chris, Great work on your articles!

            I’m planning to make the series focus on the integration of passport with angular, so I’ll be writing on things like validations and autherization middleware.

            Looking forward to seeing more of your articles. I’ll be sure to check out your passport series before I start mine.

          • http://scotch.io/ Chris Sevilleja

            Awesome. I’m excited for your articles as well. Anybody that provides good MEAN articles is helping the community immensely in my eyes.

          • Matt Cowski

            Hey Patrick, I’m in your exact position — I started programming with the excellent railstutorial and a few months later realized MEAN is where I want to be. However, since it’s so much newer, there’s not as much help. So far, the book “Master Web Applications with AngularJS” seemed just as in depth. Although it’s not really a step by step tutorial, I found it very explanatory. Another issue IMO is that there’s so many generators / kickstarters to choose from i.e. ng-boilerplate, angular-app, yo angular, yo angular-fullstack, MEAN.io, angular-fun. It’d be cool to see a someone write up a comparison / rating of all of them. Having so many config options is very unlike the Rails conventions.

          • Patrick Cauley

            It’s crazy because there are so many generators and power tools, and my problem is using a generator and having no idea how the generated app actually works and therefore having to do some guesswork. I had to switch up the way I was doing stuff and take some steps back in order to really review what I was doing.

          • Matt Cowski

            Yup, I too found myself basically reverse engineering. It helps to start from scratch and then digging into / analyzing each part. Last week I watched a tutorial on just NodeJS alone and now started incorporating i.e. grunt, angular, jade, etc… one by one. So I guess I’m kinda making my own custom generator.
            Well, if you want to chat more or work on something together, IM me mattcowski@gmail.com

      • Patrick Cauley

        Hey Tyler, I rebuilt and played with your code for the Passport app, I got it working and learned a good amount of the ME-N part of the MEAN stack, thank you so much!

        • tylerhenkel

          Awesome! Glad I could help!

  • stvogel

    Thanks for this grealt tutorial.
    Just wanted to drop, that if you’re on mac, the “npm install -g …” needs to be:
    “sudo npm install -g …”

  • http://aalaap.com Aalaap Ghag

    I have been looking for something like this for far too long! Thanks!

  • Connor James Leech

    great tutorial, more on this please!

  • Pingback: Build an Angular Todo App with a Node Backend | Tyler Henkel's Portfolio

  • http://www.chocolatejar.eu Andrej Zachar

    Hello Tyler! This project is awesome! It saved me so many days of setting things up. Please if I want to use bootstrap theme, what should I change to have a proper configuration without hacks within grunt, bower and index.html dependencies of css and js. Thank you once again for all of this! Andrej

    • tylerhenkel

      Thanks Andrej! Assuming you’re using sass, If you’d like to use a different theme just use `bower install my-bootstrap-theme` (or `bower install my-bootstrap-theme –save` if you add it to the exclude list in the ‘bower-install’ grunt task.)

      Then replace the import statement in the main.scss to point to your theme. If its a scss theme then you should be able to continue using variables like $icon-font-path.

      • http://www.chocolatejar.eu Andrej Zachar

        Thank you Tyler!

  • http://www.webfing.com king

    Thanks! Great post.

  • piet paal

    been looking to get heroku deployment working for days, now it is working. Many thanks

  • Arkadiusz Janeczko

    On of a few, writups in which everything works! Thanks!

  • Justin Diaz 

    I am building an app that requires different UI for admin services. Any tips on how should I do this? I was thinking about modifying the grunt file to watch another directory like the client directory.

  • Andrew Scheuermann

    Tyler I love angular-fullstack and I use it all the time. I’m trying to combine angular-fullstack and this post (http://www.spacjer.com/blog/2014/02/10/defining-node-dot-js-task-for-heroku-scheduler/) (minus the postgres). I went through this tutorial and built this super basic app (https://github.com/andrewscheuermann/scheduler-tester).

    TL;DR: I want to use Heroku Scheduler to run a weekly database-updating function on angelinsights.herokuapp.com.

    My main problem is that I don’t know where I can run “heroku run fileName” in the dist folder after a Grunt build. If I can run this command in the right location within Dist I can then set a scheduling event through Heroku’s scheduler to run the updating file every week.

    PS: The app in question is here (https://github.com/andrewscheuermann/angelinsights)

    Any insights you have are VERY appreciated! Thank you!

  • Nicolas Ocampo

    Thank you so much! Loving your generator so far.