webpackJsonp([0x77e219a71f28],{362:function(e,a){e.exports={data:{markdownRemark:{html:'

\n \n \n \n \n \n

\n

Introduction

\n

The following article assumes you have a basic understanding of AngularJS. Take a look at AngularJS: The Essentials if you need to get up to speed. Ready? Let\'s crack on then. We are going to make a Create Your Own Pizza form to illustrate how to bind, and in some cases build different HTML form fields. We will also cover validation of these fields and of course how to handle the form submission. Let\'s throw in some Bootstrap too!

\n

The entire code used here for our example form (pizza-form.html) and AngularJS module (app.js) has been shared on GitHub. Go ahead and download it now if you would like to read alongside the finished example.

\n

The Controller

\n

Let\'s start by creating a new file called app.js and defining an AngularJS module along with the beginnings of our controller.

\n
\'use strict\'  \n  \nvar app = angular.module(\'myApp\', [ ]);  \n  \napp.controller(\'PizzaFormController\', [\'$scope\', function($scope) {  \n      \n\t// Initialise order object\n    $scope.order = {\n        customer: {},\n        pizza: {\n            toppings: [],\n            quantity: 1\n        },\n        total: 0,\n        complete: false\n    };  \n    \n    // Initialise form submitted state\n    $scope.formSubmitted = false;  \n    \n\t// Initialise option arrays\n    $scope.pizzaSizes = [\n        { name: "Small", val: "S", price: 3.99 },\n        { name: "Medium", val: "M", price: 5.99 },\n        { name: "Large", val: "L", price: 7.99 }\n    ];  \n  \n    $scope.pizzaBases = [\n        { name: "Thin Crust", val: "thinCrust", price: 0 },\n        { name: "Original", val: "original", price: 0 },\n        { name: "Deep Pan", val: "deepPan", price: 0 },\n        { name: "Stuffed", val: "stuffed", price: 1.99 }\n    ];  \n    \n    $scope.pizzaToppings = [\n        { name: "Extra Cheese", val: "extraCheese", price: 0.50 },\n        { name: "Bacon", val: "bacon", price: 0.50 },\n        { name: "Beef", val: "beef", price: 0.99 },\n        { name: "Chicken", val: "chicken", price: 0.99 },\n        { name: "Jalapeños", val: "jalapeños", price: 0.50 },\n        { name: "Mixed Peppers", val: "mixedPeppers", price: 0.50 },\n        { name: "Mushrooms", val: "mushrooms", price: 0.50 },\n        { name: "Olives", val: "olives", price: 0.50 },\n        { name: "Pineapple", val: "pineapple", price: 0.50 },\n        { name: "Sweetcorn", val: "sweetcorn", price: 0.50 },\n        { name: "Tuna", val: "tuna", price: 0.99 }\n    ];  \n    \n    // Various methods. We\'ll get to these later.  \n        \n}]);\n
\n

Firstly we initialise the base $scope.order object which will store our customer details, pizza selections, order total and the status of the order. This is followed by initialising the form state with $scope.formSubmitted. The three items after this are arrays of objects which will be used to build our pizza options in the form.

\n

The Form

\n

Next we create our form page pizza-form.html and pull in the required files, setup a little CSS (to add an asterisk to required fields), and bind our controller to a <div> wrapper.

\n
<!DOCTYPE html>\n<html ng-app="myApp" lang="en"> \n<head>\n    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\n    <meta name="language" content="en" />\n    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />\n\t<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>\n\t<script type="text/javascript" src="app.js"></script>\n    <style>\n        .form-group.required .control-label:after { \n           content:"*";\n           color:red;\n        }\n    </style>\n</head>\n<body>\n    <div class="container">\n        <div class="row">\n            <div class="col-xs-12" ng-controller="PizzaFormController">\n                <h1>Welcome to the Pizza Palace</h1>  \n\t\t\n                ...  \n\t\t\n            </div>\n        </div>\n    </div>\n</body>\n</html>\n
\n

Let\'s add the form element just below our main heading.

\n
                <form novalidate class="col-xs-6" name="pizzaForm" ng-submit="submit()" ng-hide="order.complete">\n                ...\n                </form>\n
\n

Several things to point out here. Since HTML5, modern browsers can perform some form validation without the need for any one of a host of JavaScript plugins and libraries created over the years. However, if you need any type of validation not covered by HTML5 (or want better coverage than just modern browsers) and want to have one consistent look and feel to how you handle all validation, then we need to tell the browser to back off! Say hi to the novalidate attribute which does exactly this. The name attribute might seem trivial but note we will need this for validation later so don\'t skip it.

\n

Next up are a couple of AngularJS directives. The first, ng-submit will be covered later, but in short it hijacks the form submission and passes it to the given function. The latter, ng-hide tells AngularJS to hide the whole form if the order status is complete. Remember we intialised this to false in our controller earlier.

\n

Customer Details

\n

Now the stage is set, let\'s get to adding some form fields.

\n
                    <div class="form-group required">\n                        <h2>Your Details</h2>\n                        <label for="firstName" class="control-label">First Name</label>\n                        <input type="text" name="firstName" class="form-control input-sm" ng-model="order.customer.firstName" required />\n                        <div class="alert alert-danger" ng-show="( formSubmitted || pizzaForm.firstName.$dirty ) && pizzaForm.firstName.$invalid">\n                            <small ng-show="pizzaForm.firstName.$error.required">\n                                Please enter your first name.\n                            </small>\n                        </div>\n                        ...\n                    </div>\n
\n

Scattered throughout, you will see lots of Bootstrap CSS classes. One to note is the wrapper <div class="form-group required">. These classes relate to the CCS we added in the head of the page. This will append an asterisk to the text of any elements also tagged with the form-control class.

\n

We next need to bind, using ng-model, our input field to a model within our controller order.customer.firstName. Also note the HTML5 required attribute denoting a mandatory field. This would normally be used by the browser\'s built-in validation but will also be used by our AngularJS validation. The next block contains an error message that is conditionally shown when the ng-show directive\'s expression evaluates to true. To understand the expression, we will later delve deeper into AngularJS validation. The above also includes the customer\'s last name which is more or less the same as first name so let\'s move on.

\n

Pizza Size

\n

The next section of the form is where we actually build our pizza with the use of several other HTML elements. This is where our option arrays from the AngularJS controller come into play. We could have just created static HTML elements, but the option arrays of objects allow us more control and the abiltity to store more information for each option such as price (which will come in handy when we calculate the order total later).

\n
                    <h2>Build Your Own Pizza</h2>\n                    <p>Please select from the options below:</p>\n                    <div class="form-group required">\n                        <h3 class="control-label">Size</h3>\n                        <div class="radio" ng-repeat="pizzaSize in pizzaSizes">\n                            <label>\n                                <input type="radio" name="size" class="input-md" required ng-model="order.pizza.size" ng-change="updateOrderTotal()" value="{{ pizzaSize.val }}" /> {{ pizzaSize.name }} (&pound;{{ pizzaSize.price }})\n                            </label>\n                        </div>\n                        <div class="alert alert-danger" ng-show="( formSubmitted || pizzaForm.size.$dirty ) && pizzaForm.size.$invalid">\n                            <small ng-show="pizzaForm.size.$error.required">\n                                Please pick which size pizza you would like.\n                            </small>\n                        </div>\n                    </div>\n
\n

This time we are using ng-repeat to iterate over pizzaSizes. Note that the directive has been placed on the wrapper <div> so that we get the whole block including <label> and <input type"radio" /> repeated for each pizza size option. If you need a reminder of ng-repeat and how it works, skip over to AngularJS: The Essentials.

\n

The eagle eyed amongst you may have noticed the use of the ng-change directive on the input. Again we will cover this later but in essence the directive calls the specified function immediately on change of the value. I say immediately to make it clear that the directive does not wait until focus has moved from the field. If this were an <input type"text" />, the function would be called after every keystroke.

\n

Pizza Base

\n

When it comes to HTML <select> elements we could use ng-repeat again to create each <option> element. However, AngularJS provides a directive especially made for this purpose, ng-options.

\n
                    <div class="form-group required">\n                        <h3 class="control-label">Base</h3>\n                        <select name="base" ng-model="order.pizza.base" ng-options="pizzaBase.val as pizzaBase.name + \' +(&pound;\' + pizzaBase.price + \')\' for pizzaBase in pizzaBases" ng-change="updateOrderTotal()" required>\n                             <option value="">Please select a base</option>\n                        </select>\n                        <div class="alert alert-danger" ng-show="( formSubmitted || pizzaForm.base.$dirty ) && pizzaForm.base.$invalid">\n                            <small ng-show="pizzaForm.base.$error.required">\n                                Please select which pizza base you would like.\n                            </small>\n                        </div>\n                    </div>\n
\n

There a quite a few different comprehension expressions for this directive depending on whether we are iterating over arrays or object properties. The one used here is select as label for value in array. The first two of these represent the option\'s value and the text to be displayed, respectively. In our case that is pizzaBase.val and the expression pizzaBase.name + \' +(&pound;\' + pizzaBase.price + \')\' which concatenates the pizza base name with the price. We also see the ng-change directive, again used to update the order total.

\n

Note we have also added a default option with an empty value as we do not want to default to any of the existing options.

\n

Pizza Toppings

\n

Next up we have the pizza toppings which are all optional and so represented by checkboxes. Checkboxes can be approached several different ways depending on how you wish to use them. If we had a straight forward bunch of options to pick from and each was represented by a different variable or property in the scope, then we could just use ng-model to bind each of them. In our case however we want to capture just the ordered items in an array of pizza toppings (we aren\'t interested in what our customers don\'t want on their pizza).

\n
                    <div class="form-group">\n                        <h3>Toppings</h3>\n                        <div class="checkbox" ng-repeat="pizzaTopping in pizzaToppings">\n                            <label class="control-label">\n                                <input type="checkbox" name="topping" ng-click="updateToppings( pizzaTopping.val )" value="{{ pizzaTopping.val }}" /> {{ pizzaTopping.name }} ({{ pizzaTopping.price | currency : "&pound;" }})\n                            </label>\n                        </div>\n                    </div>\n
\n

As we are capturing our toppings in an array, we need to add (or remove) toppings when they are clicked. Therefore we use the ng-click directive to call our updateToppings() funtion in the controller.

\n
    /*\n     * On click of a pizza topping checkbox, remove the topping\n     * if already added, otherwise add it. Then update the order total.\n     * \n     * @method updateToppings\n     * @param {String} pizzaTopping The selected pizza topping.\n     */\n    $scope.updateToppings = function ( pizzaTopping ) {\n        var addTopping = true;  \n        \n        if( $scope.order.pizza.toppings.length > 0 ) {\n            for( var i=0; i < $scope.order.pizza.toppings.length; i++ ) {\n                if( pizzaTopping === $scope.order.pizza.toppings[ i ] ) {\n                    $scope.order.pizza.toppings.splice( i, 1 );\n                    addTopping = false;\n                }\n            }\n        }\n        if( addTopping === true ) {\n            $scope.order.pizza.toppings.push( pizzaTopping );\n        }\n        $scope.updateOrderTotal();\n    };\n
\n

This function will remove a topping from the array if it already exists (clearing a checkbox). Otherwise it will be added to the array.

\n

Pizza Quantity

\n

This would probably have been better suited to a <input type="number" /> but I have used a <input type="text" /> to give me an excuse to use ng-pattern. All revealed later.

\n
                    <div class="form-group required">\n                        <h3 class="control-label">Quantity</h3>\n                        <input type="text" name="quantity" ng-model="order.pizza.quantity" ng-pattern="/^[1-9]{1}[0-9]*$/" ng-change="updateOrderTotal()" required />\n                        <div class="alert alert-danger" ng-show="( formSubmitted || pizzaForm.quantity.$dirty ) && pizzaForm.quantity.$invalid">\n                            <small ng-show="pizzaForm.quantity.$error.required">\n                                Please enter how many pizzas you would like.\n                            </small>\n                            <small ng-show="pizzaForm.quantity.$error.pattern">\n                                Please enter a valid number of pizzas you would like.\n                            </small>\n                        </div>\n                    </div>\n
\n

That only leaves the submit button <input type="submit" value="Let\'s Cook!" /> which is nothing unusual. Although remember we put our ng-submit directive up in the <form> element to hijack the submission.

\n

Order Total

\n

As mentioned several times above, we are constantly updating the order total when either a value changes on a text, radio or select type input (ng-change) or a checkbox is clicked (ng-click). All of these call the same function in the controller.

\n
    /*\n     * Recalculate the order total from scratch for all ordered options.\n     * \n     * @method updateOrderTotal\n     */\n    $scope.updateOrderTotal = function () {\n        $scope.order.total = 0;\n        if( $scope.order.pizza.hasOwnProperty( \'size\' ) ) {\n            $scope.order.total += $scope.lookUpOption( $scope.pizzaSizes, $scope.order.pizza.size, \'price\' );\n        }\n        if( $scope.order.pizza.hasOwnProperty( \'base\' ) ) {\n            $scope.order.total += $scope.lookUpOption( $scope.pizzaBases, $scope.order.pizza.base, \'price\' );\n        }\n        if( $scope.order.pizza.toppings.length > 0 ) {\n            angular.forEach( $scope.order.pizza.toppings, function( orderedTopping ) {\n                $scope.order.total += $scope.lookUpOption( $scope.pizzaToppings, orderedTopping, \'price\' );\n            });\n        }\n        $scope.order.total *= $scope.order.pizza.quantity;\n    };\n
\n

This function recalculates the total by checking each option type to firstly see if anything has been ordered and if it has, looks up the price in the respective option array (see helper function below). The price is then added to the total which is presented at the bottom of the form.

\n
    /*\n     * Helper function to retrieve an option property from a provided option array.\n     * \n     * @method lookUpOption\n     * @param {Array} itemList The option array to be searched.\n     * @param {String} optionVal The option value to be looked up.\n     * @param {String} requiredVal The option value to be retrieved.\n     * @return The retrieved value found in the option array.\n     */\n    $scope.lookUpOption = function ( itemList, optionVal, requiredVal ) {\n        var foundVal;\n        angular.forEach( itemList, function( item ) {\n            if( optionVal === item.val ) {\n                foundVal = item[ requiredVal ];\n            }\n        });\n        return foundVal;\n    };\n
\n

The Validation

\n

AngularJS provides several object validation properties that are automatically added to both our form and all the inputs. Each property also has an associated CSS class (shown in braces after each property below) so we can change style according to the current validation status of the form or inputs.

\n\n

To reference the form and any inputs within, we use the form\'s name attribute. So for example we can check if the whole of our form is valid (i.e. all inputs within are valid) by checking if pizzaForm.$valid is true. Or we could check if the customer\'s first name had failed validation by checking if pizzaForm.firtName.$invalid is true.

\n

But how do we create rules? Each rule is declared as either a HTML attribute or an AngularJS directive within the field element that is to be tested. Let\'s look at the most commonly used types of validation rules that can be set for each field type:

\n\n

Let\'s take a closer look at ng-pattern as the rest are pretty self explanatory. The value of this directive can be either a regular expression string or a JavaScript RegExp object. In our pizza quantity above we used ng-pattern="/^[1-9]{1}[0-9]*$/" which restricts the input to one or more numbers only and the first number must be between 1 and 9. This is a very basic example but hopefully you get the idea that this could be an extremely powerful custom validation tool. You can find more details on all of these in the docs.

\n

Failing one or more of these rules will firstly add the $invalid property to both the form and the failing field. AngularJS will also add an $error property to the field along with the error type i.e. pizzaForm.firstName.$error.required with a value of true if no value was entered.

\n

In our pizza quantity example above we want to show an error block only if the field is invalid (pizzaForm.quantity.$invalid) and either the form has been submitted already (formSubmitted) or the field has been used (pizzaForm.quantity.$dirty). If a field is required for example then it would fail validation immediately and show the error block which wouldn\'t be nice at all ("I just got here and they are already telling me I have done something wrong!"). We only want to show our error block when either someone has entered an invalid value or has tried to submit the form without entering anything.

\n

Within the error block we also have the specific validation checks and their respective error messages which are of course only shown if the error being checked is true:

\n
                            <small ng-show="pizzaForm.quantity.$error.required">\n                                Please enter how many pizzas you would like.\n                            </small>\n
\n

The Submission

\n

Finally, we look at the submission of the form. Waaaaay back near the top of this article we saw that the <form> element contained ng-submit="submit()" which hijacks the normal http form submission and calls the enclosed function.

\n
    /*\n     * Form submit\n     */\n    $scope.submit = function () {\n        $scope.formSubmitted = true;  \n        \n        if( $scope.pizzaForm.$valid ) {\n            $scope.order.complete = true;\n        }\n    };\n
\n

Nothing ground breaking here. We state that the form has now been submitted which is then used by our validation. We also check if the whole form is valid, and if so we set the order to complete. Again, waaaaaay back up top we also added ng-hide="order.complete" to the <form> element. So on a successful submission of an order, the whole form will be hidden. In its place we\'ll show a confirmation (which we add just below the form).

\n
                <div ng-if="order.complete">\n                    <h2>Order Complete</h2>\n                    <p>Thank you {{ order.customer.firstName }} {{ order.customer.lastName }} for your order. Your <ng-pluralize count="order.pizza.quantity" when="{\'1\': \'pizza is\', \'other\': \'pizzas are\'}"></ng-pluralize> in the oven!</p>\n                    <h3>You ordered:</h3>\n                    <p>{{ order.pizza.quantity }} x {{ lookUpOption( pizzaSizes, order.pizza.size, \'name\' ) }} {{ lookUpOption( pizzaBases, order.pizza.base, \'name\' ) }} <ng-pluralize count="order.pizza.quantity" when="{\'1\': \'Pizza\', \'other\': \'Pizzas\'}"></ng-pluralize> with \n                        <span ng-if="order.pizza.toppings.length === 0"> no extra toppings.</span>\n                        <span ng-if="order.pizza.toppings.length > 0" ng-repeat="pizzaTopping in order.pizza.toppings">{{ $index !== 0 ? ", " : ""}}{{ $index === order.pizza.toppings.length - 1 ? "and " : ""}}{{ lookUpOption( pizzaToppings, pizzaTopping, \'name\' ) }}</span>.\n                    </p>\n                    <h3>Enjoy! Come again soon.</h3>\n                </div>\n
\n

The Wrap Up

\n

Well done if you made it this far! I appreciate we haven\'t looked at what should be done with the submitted order (other than display a confirmation). We could email it, trigger an alert on another system or maybe within an admin interface of the same application. We will be looking at Services in a later article which will help us to link our applications to APIs.

\n

Remember the complete code used here can be downloaded from GitHub so if you haven\'t already, go help yourself.

',frontmatter:{teaser:"Another in the AngularJS series.This time we delve into HTML forms and the many useful built-in directives. We also take at look at validation and throw in some Bootstrap for good measure.",date:"19 January 2015",path:"/blog/angularjs-forms-and-validation",title:"AngularJS: Forms & Validation"}}},pathContext:{prev:null,next:{html:'

\n \n \n \n \n \n

\n

JavaScript Objects

\n

Javascript objects can be created using new Object() or by object literal notation (preferred) and whatever properties and methods (functions within an object) we wish added.

\n
car = new Object();  \n  \ncar.manufacturer = "Bugatti";\ncar.model = "Veyron";\n
\n
car = {\n    manufacturer: "Bugatti",\n    model: "Veyron"\n}\n
\n

Unlike JavaScript primitives like string or number, objects are addressed by reference. This means that assigning an existing object to another variable will not make a copy. The new object will just point to the same object that the original one does. Changing either of these objects will change both of them.

\n
anotherCar = car;  \n  \nanotherCar.manufacturer = "McLaren";\nanotherCar.model = "P1";  \n  \nconsole.log( anotherCar ); // Object {manufacturer: "McLaren", model: "P1"}\nconsole.log( car ); // Object {manufacturer: "McLaren", model: "P1"}\n
\n

We can use Object.create() to make new objects that inherit all properties and methods from an existing object. However we still have to replace/set all the values of the new object so no real advantage to this approach. We may as well just create new objects from scratch.

\n
anotherCar = Object.create( car );  \n  \nanotherCar.manufacturer = "McLaren";\nanotherCar.model = "P1";  \n  \nconsole.log( anotherCar ); // Object {manufacturer: "McLaren", model: "P1"}\nconsole.log( car ); // Object {manufacturer: "Bugatti", model: "Veyron"}\n
\n

So what if we want lots of different objects that are of the same type? What is the best approach to handling object creation?

\n

Object Constructor Functions

\n

All built-in objects (with the exception of Math) have their own constructors. When we use the new keyword, we are telling JavaScript to use the constructor of the following object ie. new Date(). Constructors may also receive arguments to be used within the construction process.

\n

A constructor function is similar to a class in other OO languages in that we can define properties to store our data, and methods to perform operations on this data. It is accepted convention in JavaScript to always capitalise the first character of a constructor function name to help differentiate it from regular functions.

\n
function Car( manufacturer, model, wheels ) {\n    this.manufacturer = manufacturer;\n    this.model = model;\n    this.wheels = wheels;\n    this.start = function() {\n        console.log( "Nice " + this.manufacturer + " " + this.model + ", let\'s roll!" );\n    };\n}\n
\n

Note the use of the this keyword. In the context of a constructor function (when called with the new keyword), this relates to the object being created. Also note that we are not returning anything either as the properties and methods are being defined directly on this object.

\n

We can now create/instantiate new objects with our constructor and pass in the values to be set.

\n
var modelS = new Car( "Tesla", "Model S", 4 );  \n  \nconsole.log( modelS ); // Car {manufacturer: "Tesla", model: "Model S", wheels: 4, start: function}\nmodelS.start(); // Nice Tesla Model S, let\'s roll!\n
\n

Objects have a constructor property which is automatically set with a reference to the constructor function used to create it. We can check this with the following methods:

\n
console.log( modelS.constructor == Car ); // true\nconsole.log( modelS instanceof Car ); // true\n
\n

However, a problem remains that new objects all have a copy of all the properties and methods, regardless of whether or not they will every need or use them. What if we could keep certain properties and methods in a central place so that all instances of an object could access them only when required?

\n

Object Prototypes

\n

Every object has a prototype property which, as it sounds, is a kind of template that an object\'s constructor uses when creating new instances of itself.

\n

Every built-in object (with the exception of Math which doesn’t have a constructor) has a prototype property with its own properties and methods defined within. Thus an instance of Array or Date for example inherits a multitude of methods from its constructor\'s prototype without carrying the weight of these within the instance itself. Objects created using new Object() or object literal notation directly inherit properties and methods from Object.prototype such as constructor, hasOwnProperty(), toString(), etc.

\n

We can define our own prototypes for our constructor functions and move any properties or methods that we wish to share over to the prototype. Let\'s rewrite our Car example:

\n
function Car( manufacturer, model, wheels ) {\n    this.manufacturer = manufacturer;\n    this.model = model;\n    this.wheels = wheels;\n}  \n  \nCar.prototype.start = function() {\n    console.log( "Nice " + this.manufacturer + " " + this.model + ", let\'s roll!" );\n};  \n  \nvar modelS = new Car( "Tesla", "Model S", 4 );  \n  \nmodelS.start(); // Nice Tesla Model S, let\'s roll!\n
\n

Note that we could have defined the prototype with object literal notation. This has the advantage of being able to define multiple properties and methods with less code. However, as this effectively replaces the whole property, we have to redefine the constructor property.

\n
Car.prototype = {\n    constructor: Car,\n    start: function() {\n        console.log( "Nice " + this.manufacturer + " " + this.model + ", let\'s roll!" );\n    }\n}\n
\n

Objects also have a prototype attribute or object (not to be confused with the prototype property above) which is automatically set and shows where an object descends from i.e. its parent. The attribute stores a reference to the constructor\'s prototype. So for example a new Object() would descend directly from Object.prototype, an object instantiated from new Date() would descend from Date.prototype, and in our Car example an object would descend from Car.prototype. We can use the following methods to check which prototype was used to create an object:

\n
console.log( Car.prototype.isPrototypeOf( modelS ) ); // true\nconsole.log( Object.getPrototypeOf( modelS ) === Car.prototype ); // true (IE9+)\n
\n

Inheritance and the Prototype Chain

\n

JavaScript objects can inherit from other objects, which can in turn inherit from other objects, and so on. If we create a new Date object for example, this would inherit from Date.prototype which in turn inherits from Object.prototype, creating a chain of inheritance. All objects, be they custom or built-in, ultimately inherit from Object.prototype.

\n

When a property is referred to, or a method is called, JavaScript will firstly check in the current object to see if that property or method is defined. If it isn\'t, the object\'s prototype attribute is looked up (following the prototype chain) and the object defined there is then checked. This chain lookup continues until a matching property or method is found.

\n

There are several different approaches/patterns used to implement inheritance for our own JavaScript objects, each with their own pros and cons. Let\'s look at two of the most popular patterns using our Car example again and add in a new parent object type Vehicle with its own properties and methods.

\n

Combination Inheritance

\n

We saw earlier that we can create an object via a constructor function, and we can also add properties and methods to the constructor\'s prototype that we wish to share with all child objects. We run into problems though if any of the constructor properties hold a composite value such as an array or an object. Primitive values such as string or number are fine because the value will likely be replaced by the instantiated object. Composites however are only references to an object. This means that any instantiated objects would inherit the reference to the same property object. Altering that property value, such as adding an item into an array, would change the referenced object and so change the value for all child objects. So what can be done?

\n

This pattern is so called because it combines constructor stealing with prototype chaining. It is an attempt to replicate in some ways a classical inheritance pattern found in many other Object Oriented languages. Basically, we use prototype chaining to inherit the properties and methods defined on the constructor\'s prototype and we inherit the instance properties (defined in the constructor itself) by stealing the whole constructor. In practice we achieve this by setting the Car prototype attribute to inherit from the Vehicle.prototype (ensure this is done before defining any prototype properties or methods on Car). Then we tell the Car constructor to call (steal) the Vehicle constructor so inheriting it\'s properties and methods.

\n
function Vehicle( colour ) {\n    this.purpose = "To move things from A to B.";\n    this.colour = colour;\n}  \n  \nVehicle.prototype.howManyWheels = function() {\n    console.log( "I\'m rolling on " + this.wheels + " wheels baby!" );\n}  \n  \nVehicle.prototype.whatColour = function() {\n    console.log( this.colour + " is the best colour by far!" );\n}  \n  \nfunction Car( manufacturer, model, wheels, colour ) {\n    // Call the parent constructor. Note we can now pass arguments too. Woop!\n    Vehicle.call( this, colour );  \n  \n    this.manufacturer = manufacturer;\n    this.model = model;\n    this.wheels = wheels;  \n  \n}  \n  \n// And we inherit the parent prototype\nCar.prototype = Object.create( Vehicle.prototype );  \n  \nCar.prototype.start = function() {\nconsole.log( "Nice " + this.manufacturer + " " + this.model + ", let\'s roll!" );\n};  \n  \nvar robin = new Car( "Reliant", "Robin", 3, "Risky Red" );  \n  \nrobin.start(); // Nice Reliant Robin, let\'s roll!\nrobin.howManyWheels(); // I\'m rolling on 3 wheels baby!\nrobin.whatColour(); // Risky Red is the best colour by far!  \n  \nvar veyron = new Car( "Bugatti", "Veyron", 4, "Storm Silver" );  \n  \nveyron.start(); // Nice Bugatti Veyron, let\'s roll!\nveyron.howManyWheels(); // I\'m rolling on 4 wheels baby!\nveyron.whatColour(); // Storm Silver is the best colour by far!  \n  \nconsole.log( Car.prototype.isPrototypeOf( robin ) ); // true\nconsole.log( Vehicle.prototype.isPrototypeOf( robin ) ); // true\n
\n

Prototypal Inheritance

\n

Whilst the Combination Inheritance pattern is very popular, JavaScript is a class-less language and we can implement inheritance perfectly well without classes or constructors. As we know, objects can inherit from other objects, which can in turn inherit from other objects, and so on. Not a class in sight! This form of inheritance is very easy to understand compared with some other patterns. We can use a mix of object literal notation and the Object.create() method to make our objects which makes our code easier to read. However we need to define every property of every object we create rather than just passing the values in as arguments to a constructor.

\n
var vehicle = {\n    purpose: "To move things from A to B.",\n    colour: "Rainbow",\n    howManyWheels: function() {\n        console.log( "I\'m rolling on " + this.wheels + " wheels baby!" );\n    },\n    whatColour: function() {\n        console.log( this.colour + " is the best colour by far!" );\n    }\n};  \n  \n  \nvar car = Object.create( vehicle );  \n  \ncar.manufacturer = "";\ncar.model = "";\ncar.wheels = "";\ncar.start = function() {\n    console.log( "Nice " + this.manufacturer + " " + this.model + ", let\'s roll!" );\n};  \n  \n  \nvar robin = Object.create( car );\nrobin.manufacturer = "Reliant";\nrobin.model = "Robin";\nrobin.wheels = 3;\nrobin.colour = "Risky Red";  \n  \nrobin.start(); // Nice Reliant Robin, let\'s roll!\nrobin.howManyWheels(); // I\'m rolling on 3 wheels baby!\nrobin.whatColour(); // Risky Red is the best colour by far!  \n  \n  \nvar veyron = Object.create( car );\nveyron.manufacturer = "Bugatti";\nveyron.model = "Veyron";\nveyron.wheels = 4;\nveyron.colour = "Storm Silver";  \n  \nveyron.start(); // Nice Bugatti Veyron, let\'s roll!\nveyron.howManyWheels(); // I\'m rolling on 4 wheels baby!\nveyron.whatColour(); // Storm Silver is the best colour by far!\n
\n

Note that both of the above patterns make use of Object.create(). This method has only been a native to JavaScript since the definition of ECMAScript 5 (thanks to Douglas Crockford). This means the method is not available to older browsers such as IE8 or older. We can however create the method if it isn\'t already defined:

\n
if ( typeof Object.create !== \'function\' ) {\n    Object.create = function ( o ) {\n        function F() {}\n        F.prototype = o;\n        return new F();\n    };\n}\n
\n

Shadowing And Deleting

\n

So what happens if an object defines a property or method with the same name as that of one of its ancestors? The descendant\'s property or method would shadow the ancestor\'s and stop the chain lookup right there. Other objects that also inherit from the same ancestor but have not shadowed the same property or method, will still use that of the ancestor.

\n
robin.start = function() {\n    console.log( "Three wheels is the only way to travel!" );\n};  \n  \nrobin.start(); // Three wheels is the only way to travel!  \n  \nveyron.start(); // Nice Bugatti Veyron, let\'s roll!\n
\n

To allow an object to inherit the property or method again, we must do more than just set the value to null or undefined. The delete operator must be used to completely remove the shadowing property or method.

\n
delete robin.start;  \n  \nrobin.start(); // Nice Reliant Robin, let\'s roll!\n
', id:"/home/geoff/www/cornerpiece/geoffford.co.uk/src/pages/blog/12-01-2015-object-oriented-javascript-cheat-sheet/index.md absPath of file >>> MarkdownRemark",frontmatter:{date:"2015-01-12T11:33:21Z",path:"/blog/object-oriented-javascript-cheat-sheet",title:"Object Oriented JavaScript Cheat Sheet"}}}}}}); //# sourceMappingURL=path---blog-angularjs-forms-and-validation-3551b4c71b81277609c9.js.map