Beginning MEAN Stack

Post on 18-Jul-2015

272 views 4 download

transcript

Rob Davarnia

@robdvr - robdvr@gmail.com - robdvr.com

About meSenior Full Stack Developer at GigaSavvy

Passionate about Ruby on Rails, Node.js, and Angular

Agenda

Explore MEAN Stack technologies

Deploy a sample application with authentication to heroku

MEAN

What’s MEAN Stack?

MEAN Stack is a full-stack JavaScript solution that helps you build fast, robust and maintainable production web

applications using MongoDB, Express, AngularJS, and Node.js.

What’s a Framework?structure that includes libraries of code

1. Code and File Organization

2. Libraries & Extensions3. Faster Development

4. Community 5. Updates

What’s a dev Stack?

LAMP - Linux, Apache, MySQL, PHP

.net - Windows, IIS, C#, MSSQL Server

Java - Tomcat, Java, JSP, Oracle

What’s MongoDB?MongoDB is a NoSQL document-store database

What’s express?Express is a web application framework built on

node.js which comes with a set of features for building single-page, multi-page, and hybrid web apps.

What’s AngularJS?AngularJS is an application framework that lets you extend HTML and teach it new tricks. The code is

expressive, readable, and quick to develop.

What’s node.js?Open source

Server side JavaScript

Executed by the V8- a JavaScript engine developed by Google which is used in Chrome

Comes with built-in library to act as a web server, like Apache.

Why MEAN Stack?

All of these components use JavaScript / JSON.

One language, same context

Consistent

Scalability

Asynchronous

Who is using MEAN?

MEAN Stack recap

MongoDB - Database

ExpressJS - Web Application Framework

AngularJS - Frontend Framework

NodeJS - Web Server

Overview

Let’s talk about node.js!

Package Management

NodeJS module package manager (NPM)

There’s a module for almost anything you can imagine

Simple to use

Blocking I/O vs. Non-Blocking I/O

http://www.toptal.com/nodejs/why-the-hell-would-i-use-node-js

I/O Bound vs. CPU Bound Applications

CPU Intensive vs. IO Intensive

node.js is a good solution for IO intensive apps

web applications are usually IO intensive

Background jobs for processing CPU intensive workload

Event Loop in Node (Reactor Pattern - Single Thread)

JavaScript runtime contains a message queue which stores a list of messages to be processed and their associated callback functions.

These messages are queued in response to external events (such as a mouse being clicked or receiving the response to an HTTP

request) given a callback function has been provided. If, for example a user were to click a button and no callback function was

provided – no message would have been enqueued…

Synchronous Calls

Code execution will block (or wait) for the call to return before continuing.

App will not execute any further, which could be perceived by the user as latency or performance lag in your app.

Node.js Asynchronous Calls

Calls do not block (or wait) for the call to return from the server.

Execution continues on in your program, and when the call returns from the server, a "callback" function is executed.

Sync vs. Async

Hello World! (1)

Create a file called app.js

Hello World! (2)var http = require('http');

http.createServer(function (req, res) {

res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');

}).listen(3000, '127.0.0.1');

console.log('Server running at http://127.0.0.1:3000/');

Hello World! (3)

$ node app.js

(run the above command to start)

Lab1

1. Create the Hello World Application

2. Run the app

3. Check your browser

Let’s talk about express!

What was express again?

Web application framework

(like Ruby on Rails, asp.net, Sinatra, django, and etc.)

Why use express.js?

- Ability to use CSS Preprocessors like Sass/Less/Stylus

- Light weight/Fast

- Better Code Structure with

- Model View Controller (MVC)

- Routing

- Template flexibility (hogan, ejs, jade)

Model View Controller

CONTROLLER

VIEW MODEL

DATABASE

BROWSER ROUTER1

2

34

5

How to create a new express app? (1)

- Ensure you have express-generator installed globally $ npm install express-generator -g

- Command Options $ express -h

1. Create a new app$ express myapp --hogan --css less

How to create a new express app? (2)

2. Install dependencies$ cd myapp && npm install

3. Run the app$ DEBUG=myapp:* ./bin/www Run the app on Windowsset DEBUG=myapp & node .\bin\www

4. Visit your browserhttp://localhost:3000/

Lab2

1. Create the Hello World Express Application

2. Run the app

3. Check your browser

Hands on: anatomy of a basic express app

Lab3

1. Create a new route

2. Edit the content displayed & Save

3. Check your browser

Auth with Passporthttp://passportjs.org/

Let’s talk about MongoDB!

What’s a document store?

Document stores provide an alternative to relational databases (ex. mysql, postgres), not a replacement.

Each has its place.

CAP Theorem (1)

Consistency: All the data change can be seen by all nodes.

Availability: Reads and Writes are guaranteed to have a response.

Partition Tolerance: the system will continue working even if any number of messages sent between nodes is lost.

CAP Theorem (2)Each database engine is designed prioritize two of these.

Understanding these tradeoffs helps in choosing the correct data stores in different layers of an application.

Document Store 1

{ "_id": 1, "firstname": "Rob", "lastname": "Davarnia", "phone": "9491234567", "email": "robdvr@gmail.com" }

Rob Davarnia 9491234567

robdvr@gmail.com

Document Store 2

Product

T-ShirtColor: YellowPrice: $20.00

Brand Name:

Nike

Brand Website: nike.com

{ "_id": 2, "name": "T-Shirt", "color": "Yellow", "price": "20.00", "brand": { "_id": 223, "name": "Nike", "website": "www.nike.com" } }

MongoDB Pros & Cons

MongoDB Pros - Schema-less Flexible

{ "_id": 2, "name": "T-Shirt", "color": "Yellow", "price": "20.00", "brand": { "_id": 223, "name": "Nike", "website": "www.nike.com" } }

MongoDB Pros - BSONBSON is a binary representation of JSON

documents. JSON everywhere!

{ "_id": 2, "name": "T-Shirt", "color": "Yellow", "price": "20.00", "brand": { "_id": 223, "name": "Nike", "website": "www.nike.com" } }

MongoDB Pros - Sharding & ScalingSharding is the process of storing data records

across multiple machines and approach to meeting the demands of data growth

MongoDB Pros - Map/ReduceProcessing and generating large data sets with a parallel, distributed algorithm on a

cluster.

MongoDB Cons - Data size

Typically higher data size because of the repeated field names stored

MongoDB Cons - Less Flexible

Less flexibility for querying (no joins!!)

MongoDB Cons - Transactions

No support for transactions. Some atomic operations are supported.

MongoDB Cons - Maturity

Still not as mature as Relational Databases

MongoDB Terms

RDBMS MongoDB

Table, View Collection

Row JSON Document

Index Index

Join Embedded Document

Partition Shard

Partition Key Shard Key

Mongoose

Object Modeling for MongoDB

http://mongoosejs.com/

Let’s talk about AngularJS!

What is AngularJS?

Javascript Framework maintained by Google.

Model-View-Controller (MVC or MV*)

Makes development and testing easier

Teaches HTML new tricks!

Model-View-Controller (MVC)

Model: handles your data

View: presentation of data to user

Controller: handles interaction/business logic

Quick Web History

1996 - Microsoft introduces the iframe in IE

1999 - Microsoft introduces the XMLHTTP ActiveX control

2004 - Gmail & Kayak, two heavily ajax’ed apps

2005 - Jesse James Garrett’s article coins the phrase AJAX

2006 - jQuery introduced

*Slide by Troy Miles - http://therockncoder.blogspot.com/

How can Angular help?

Integrate in parts of your existing website

Single Page Applications (SPA)

How can Angular help?

Integrate in parts of your existing website

Single Page Applications (SPA)

Existing Website

Single Page App

How a Single Page Application works?

CONTROLLER

VIEW MODEL

RESTful API

BROWSER ROUTER1

2

34

5

DATABASE

Feature - Two Way Data-binding

- When the model gets updated, the UI (View) gets updated

- When UI gets updated, the changes are reflected back to the model

Feature - Model View Controller

CONTROLLER

VIEW MODEL

DATABASE

BROWSER ROUTER1

2

34

5

Feature - Deep Linking

- Deep linking allows AngularJS to get back to the state it was depending on the URL

- Using the “back” button is okay!- Hyperlinks won’t break things

Feature - Dependency Injection

- Design pattern that implements inversion of control for libraries

- Dependency passed into one or multiple objects

- Easier to test

- Harder to break apps

- If any underlying code changes in your dependency, the object using it doesn’t care about implantation

Feature - Dependency Injection (2)

Angular Big picture!

How Angular works?• Browser loads the HTML and parses into DOM

• Browser loads angular.js script

• Angular waits for DOMContentLoaded event

• Angular looks for ng-app directive, which designates the app boundary

• The module specified in ng-app is used to configure $injector

• The $injector is used to create the $compile service as well as the $rootScope

• $compile service is used to compile the DOM and link it with $rootScope

• The ng-init directive assigns World to the name property on the scope

• {{ name }} interpolates the expression to “Hello World!”

Angular Terms - Controller

Interacts with Model

Sets up what’s needed for presentation (View)

Constructs model and pass it along to view along with callbacks

Angular Terms - Model

Data which gets combined with the template to produce the view

Angular Terms - View

What user sees.

Starts as a template, and then it is merged with the model, and finally rendered into the

browser DOM

Angular Terms - $scope

The scope is responsible for detecting changes to the model and provides the execution for

expressions.

Also represents the application model.

Angular Terms - Directives

A directive is a behavior or DOM transformation which is triggered by the presence of a custom attribute, element name, or class name.

They make HTML cooler!

Angular Terms - Filters

Format and transform data. example: make text uppercase

Angular Directives (1)• ng-app

Declares an element as a root element of the application allowing behavior to be modified through custom HTML tags.

• ng-bindAutomatically changes the text of a HTML element to the value of a given expression.

• ng-modelSimilar to ng-bind, but allows two-way data binding between the view and the scope.

• ng-class Allows class attributes to be dynamically loaded.

• ng-controllerSpecifies a JavaScript controller class that evaluates HTML expressions.

Angular Directives (2)• ng-repeat

Instantiate an element once per item from a collection.

• ng-show & ng-hideConditionally show or hide an element, depending on the value of a boolean expression.

• ng-switch Conditionally instantiate one template from a set of choices, depending on the value of a selection expression.

• ng-viewThe base directive responsible for handling routes that resolve JSON before rendering templates driven by specified controllers.

• ng-ifBasic if statement directive which allow to show the following element if the conditions are true.

How to create an Angular app?

1. Include angular.js library

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>

2. Create AngularJS Application

<html ng-app></html> —OR—<html ng-app=”demoApp”></html> —OR—<div ng-app></div> —OR—<div ng-app=”demoApp”></div>

Lab / Hands on

1. Create an angular.js application

2. Write a simple expression to ensure angular is working

ex: {{ 1+1 }}

Simple Data Binding

<input type="text" name="name" ng-model="name" placeholder="Type your name">

<h3> {{ name }} </h3>

Lab

1. Create an angular.js application

2. Write a simple data binding with an input element and display

3. Type and see the magic!

Creating Controllers

var app = angular.module('myApp', []);

app.controller('MyController', ['$scope', function($scope){

$scope.name = "hello";

}]);

<div ng-controller="MyController"> {{ name }}</div>

app.js

index.html

Lab1. Create an angular.js application

2. Create an additional script (app.js)

3. Include your script

4. Declare your module name

5. Create a controller

6. Add a model to $scope

7. Interpolate the model variable in your view

Creating Controllers + Two Way Data Binding

var app = angular.module('myApp', []);

app.controller('MyController', ['$scope', function($scope){

$scope.name = "hello";

}]);

<div ng-controller="MyController">{{ name }} <input type="text" name="name" value="" ng-model="name" placeholder="Type your name">

</div>

app.js

index.html

Lab1. Create an angular.js application

2. Create an additional script (app.js)

3. Include your script

4. Declare your module name

5. Create a controller

6. Add a model to $scope

7. Interpolate the model variable in your view

8. Add an input text field with the same model name

9. Change the text and see what happens

Some Angular Tags (1)Bind (ng-bind):

1. <span ng-bind=“{expression}”></span>2. {{ name }}https://docs.angularjs.org/api/ng/directive/ngBind

Loops (ng-repeat):<ul> <li ng-repeat=“item in items”>{{ item }}</li> </ul>https://docs.angularjs.org/api/ng/directive/ngRepeat

Some Angular Tags (2)

If statement (ng-if):

<div ng-if=“checked”>Show if true!</div>https://docs.angularjs.org/api/ng/directive/ngIfIncluding templates (ng-view):

<div ng-view=“_partial.html”></div>

Some Angular Tags (3)

Show and Hide (ng-show / ng-hide):

<div ng-show=“checked”>Show if true!</div>

<div ng-hide=“checked”>Hide if true!</div>

Using ng-repeat

<div ng-controller="MyController"> <ul> <li ng-repeat="person in people"> <h2>{{ person.name }}</h2> <p>Age: {{ person.age }} | Category: {{ person.category }}</p> </li> </ul>

</div>

index.html

Lab1. Create an angular.js application

2. Create an additional script (app.js)

3. Include your script

4. Declare your module name

5. Create a controller

6. Copy the list of people and add it to $scope

7. Use ng-repeat to display your data

Using ng-if

<input type="checkbox" ng-model="checked" ng-init="checked=true" /> Toggling this will show and hide the text!!<br /><br />

<span ng-if="checked"> This is removed when the checkbox is unchecked.</span>

index.html

Lab1. Create an angular.js application

2. Create an additional script (app.js)

3. Include your script

4. Declare your module name

5. Create a checkbox form tag and assign a model

6. Create a span/div and using ng-if and checkbox’s model toggle

Using ng-show / ng-hide

<input type="checkbox" ng-model="checked" ng-init="checked=true" /> Toggling this will show and hide the text!!<br /><br />

<span ng-if="checked"> 1.This is removed when the checkbox is checked.</span><span ng-hide="checked"> 2.This is removed when the checkbox is unchecked.</span>

index.html

Lab1. Create an angular.js application

2. Create an additional script (app.js)

3. Include your script

4. Declare your module name

5. Create a checkbox form tag and assign a model

6. Create two span/divs and use ng-show on one. Use ng-hide on the other and bind to checkbox’s

model toggle

Using Filters!

<input type="text" ng-model="search" name="search" value="" placeholder="Search">

<ul> <li ng-repeat="person in people | filter:search"> <h2>{{ person.name }}</h2> <p>Age: {{ person.age }} | Category: {{ person.category }}</p> </li></ul>

index.html

Lab

1. Copy your ng-repeat application

2. Add an input field with a model

3. Add the input field model as a filter to your ng-repeat

4. Start typing and see what happens!

Using orderBy

<select name="sortField" ng-model="sortField"> <option value="name">Name</option> <option value="age">Age</option> <option value="category">Category</option></select>

<select name="sortBy" ng-model="sortBy"> <option value="">ASC</option> <option value="reverse">DESC</option></select>

<ul> <li ng-repeat="person in people | filter:search | orderBy: sortField : sortBy"> <h2>{{ person.name }}</h2> <p>Age: {{ person.age }} | Category: {{ person.category }}</p> </li></ul>

index.html

Lab1. Continue with your existing search application

2. Add a select option with a model

3. Add two options to your select with the following values “”,”reverse”

4. Create another select option

5. Add your categories within the new select option

6. Use “orderBy” filter

Using ng-click

var app = angular.module('myApp', []);

app.controller('MyController', ['$scope', function($scope){

$scope.showAlert = function() { alert("Show Alert!"); };

}]);

<div ng-controller="MyController"> <a href="" ng-click="showAlert()">Show Alert!</a>

</div>

app.js

index.html

Lab

1. Create a blank angular application

2. Add a custom controller

3. Add a function to your controller’s scope, and within that function make an alert or log to

console

4. Create a link with ng-click linked to the function you made

Embedding images using ng-src

<ul> <li ng-repeat="person in people">

<img ng-src="{{ person.image }}" alt="">

<h2>{{ person.name }}</h2> <p>Age: {{ person.age }} | Category: {{ person.category }}</p> </li> </ul>

index.html

Lab

1. Copy the ng-repeat application

2. Add images to your people scope model

3. Add an image tag (img) to your index.html’s ng-repeat

4. Use ng-src to link to the person’s image source

AJAX using $http service

app.controller('MyController', ['$scope', '$http', function ($scope, $http) {

$http.get('people.json').success(function(data){ $scope.people = data; });

}]);

app.js

https://docs.angularjs.org/api/ng/service/$http

Lab

1. Copy your ng-repeat application

2. Create a file named people.json that includes your data.

3. Add $http service dependency to your controller

4. Use plnkr.co or a web server to run the app and see the results. (You won’t be able to make the XHR request if you aren’t running a web server)

Using ng-include

<div ng-include="'nav.html'"></div>

index.html

<!—- html code here —->

nav.html

Lab

1. Create a blank angular application

2. Add a custom controller

3. Add a function to your controller’s scope, and within that function make an alert or log to

console

4. Create a link with ng-click linked to the function you made

How to make angular routes?

1. Include angular-route.js library

2. Inject ‘ngRoute’ to app module

3. Inject ‘$routeProvider’ to your app as a config 4. define your routes!

app.config(['$routeProvider', function( $routeProvider ) {

$routeProvider.when('/', { templateUrl: 'homepage.html', controller: 'HomeController' });

}]);

How to make angular routes? (2)

- Nest other routes by appending ‘.when()’

- the fallback route is defined “otherwise”

app.config(['$routeProvider', function( $routeProvider ) {

$routeProvider.when('/', { templateUrl: 'homepage.html', controller: 'HomeController' }). when('/about',{ templateUrl: 'about.html', controller: 'AboutController' }). otherwise({ redirectTo: '/' }); }]);

How to make link to other routes?

<a ng-href="#/" href>Home</a> <a ng-href="#/about" href>About</a>

Lab1. Create a blank angular application

2. Include angular-route library and inject the appropriate dependencies

3. Make a 2 custom controllers

3. Make 2 custom views for each controller

5. Create 2 routes

6. Declare ng-view on a div element in your index.html

7. Using ng-href create to hyperlinks to the different views

How to make angular routes? (3)

app.config( ['$routeProvider', function($routeProvider){ $routeProvider.when('/people', { templateUrl: 'people.html', controller: 'PeopleController' }). when('/person/:id', { templateUrl: 'single_person.html', controller: 'PersonDetailController' }). otherwise({ redirectTo: '/people' }); }]);

Forms & Validation

Basic Form with ng-model data binding

<input type="text" ng-model="person.name">

Angular Form Validations$pristine: It will be TRUE, if the user has not interacted with the form yet

$dirty: It will be TRUE, if the user has already interacted with the form.

$valid: It will be TRUE, if all containing form and controls are valid

$invalid: It will be TRUE, if at least one containing form and control is invalid.

$error: Is an object hash, containing references to all invalid controls or forms, where:

- keys are validation tokens (error names)

- values are arrays of controls or forms that are invalid with given error.

Angular Form Validation CSS Classes

ng-pristine

ng-dirty

ng-valid

ng-invalid

.ng-dirty{ background-color: yellow;}

CSS Example

Angular Form Validation Usage

myForm.$dirty

In Form

myFor.fieldName.$dirty

For field

.ng-dirty{ background-color: yellow;}

In CSS

Angular Form Rules <input

ng-model="{ string }"

name="{ string }"

required

ng-required="{ boolean }"

ng-minlength="{ number }"

ng-maxlength="{ number }"

ng-pattern="{ string }"

ng-change="{ string }">

</input>

How to use Angular Form Validations? (1)

1. Add a name to your Form element

<form name=“myForm”>

2. Disable default HTML5 browser validations

<form name=“myForm” novalidate>

3. Create a form element and make it required

<input type="text" name="user" ng-model="user" required>

How to use Angular Form Validations? (2)

4. Create appropriate HTML to display field errors

<input type="text" name="user" ng-model="user" required>

<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">

<span ng-show="myForm.user.$error.required">Username is required.</span>

</span>

5. Activate/Deactivate the Submit Button as needed

<input type="submit"

ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||

myForm.email.$dirty && myForm.email.$invalid">

Lab

1. Create a form with appropriate name and properties

2. Add a field to your form

3. Add a submit button

4. Add validation to your field, and disable your submit button if the form is invalid

Unit Testing

Unit Testing

Separation of Concerns

Testing your application in small units to make sure they are doing the right thing

Unit Testing Tools

Unit Testing ExampleGrouping Tests

describe("sorting the list of users", function() {

// individual tests go here

});

Individual test

describe('sorting the list of users', function() {

it('sorts in descending order by default', function() {

// your test assertion goes here

});

});

Unit TestingFurther reading

https://docs.angularjs.org/guide/unit-testing

MEAN.js (Yeoman)

Generator for Yeoman to quickly create MEAN applications

Comes with Grunt, Bower, and Passport

What’s Grunt?A JavaScript-based task runner to perform repetitive tasks.

Grunt helps us run the web server and compile CSS/JS.

How does Grunt work?

Grunt runs with what’s needed using Gruntfile.js which includes all the settings for grunt

What’s Bower?Package manager for anything you need to build your frontend

How does Bower work?bower install <package> -- save

Bower manages front-end packages and tracks them in

bower.js file

Creating your first application

yo meanjs

Run it!

grunt

you should be able to pull the site in a browserhttp://localhost:3000

Lab

1. Create your first MEAN.js application

2. Make sure Mongodb is running

3. Start your application

4. Navigate to http://localhost:3000

CRUD (Database Operations)

CREATE

READ

UPDATE

DELETE

Deploying to Heroku

Why use Heroku?

Heroku is a PaaS (Platform as a Service)

You don’t need to manage servers!

You can focus on building your app and making your users happy!

Heroku has addons.

What’s involved?

1. Create a new project

2. Initiate a git repository

3. Add remote branch

4. Push to branch

5. Sit-back and Enjoy!

Furthur Heroku Help

https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up

https://devcenter.heroku.com/articles/deploying-nodejs

https://devcenter.heroku.com/articles/nodejs-support

Rob Davarnia

@robdvr - robdvr@gmail.com - robdvr.com

Thank you for coming!