How do I disable an HTML element with Angular ?

Angular

Angular logo - disable

Set the disabled attribute to the result of an expression and Angular will disable / enable the element for you as needed.

Example # 1

In example # 1, we have our component. There are two properties we are interested in: count and buttonDisabled. We will leverage these in our template.

Example # 2

In example # 2, we have our template. There are three buttons. The first two buttons toggle each other. That is to say, when the first button is clicked it is destroyed, and the second button is created. Conversely, when the second button is clicked, it is destroyed and the first button is created. All of this happens because each button has an ngIf attribute. That attribute is watching for the value of the buttonDisabled property. Also, each button has a click attribute. In each case, clicking the button updates the value of the buttonDisabled property.

Important note: these two buttons are for demonstration purposes only. The focus of this article is the Angular [disabled] attribute.

Next, take a look at the third button. It has a disabled attribute. That attribute is set to toggle based on the buttonDisabled property. So when the buttonDisabled property is true, that third button is disabled. And when the buttonDisabled property is false, the third button is not disabled.

Video Example Code

If you want to download the example code, visit this Github page, and then follow the instructions: bit.ly/kcv-angular-disabled-attribute

Getting Started with Backbone.js Models – Introduction

Backbone

Backbone.js LogoLearn how Backbone.js Models provide abstraction that simplifies data management in your single page application

In my previous articles about Backbone.js, I covered the basics of routes and views. I chose those areas as starting points because they are a bit easier to digest and put to use. For example, you can put together simple pages that demonstrate routes and views. To me, these are “quick wins.”

But data is where the real action is. The whole point of a single page application (aka “spa”), is that the page loads, you pull in data, display the data, possibly allow the user to change some of the data, and update the page accordingly. If there is no data in the mix, it’s just a static web page. Even in that scenario, Backbone routes and views can be very helpful because they force you to organize your code so that it is easy to read, manage and extend. But when you need to consume, display and manage data, Backbone really shines.

Why Backbone Models?

Well, in short: Backbone Models wrap your data with super-useful functionality, providing time-saving abstraction.

What?

Ok, consider the following data:

Now, that all seems nice. But what if you needed to run a function as soon as that object is created? You would need to write a function that “creates” the object first, and then calls a callback (a typical approach). Ok, but now what if you wanted to have a function that was executed any time that the data changes? Well, then you would need a “setter” method, that… yep…. calls a callback. And then what about if the “setter” method had to return only the data that was changed? Oh yeah, and it has to return the previous value of any changed data as well. This is more than a few lines of code.

Now, what if you realized that a giant e-commerce app you are building will probably need all of that functionality, but there will be different kinds of data and you will probably need even more data management tools

All of this (and more) has already been done for you: Backbone.js Models.

Example # 1

In Example # 1, we have created a variable named “salesperson”. As a result, this variable becomes a constructor function. (If you are not familiar with the concept of JavaScript constructor functions, you might want to review this article: What is the difference between an Object Literal and an Instance Object in JavaScript ? | Kevin Chisholm – Blog )

It is important to understand that you are “extending” the Backbone Model “class”. This means that you are creating a constructor function that inherits from the Backbone Model constructor. You will never execute your SalesPerson constructor. In other words, you will never do this:

You will instantiate that constructor in this manner:

In this scenario, “someVariable” becomes an “instance” of the SalesPerson constructor, which inherits from the Backbone Model constructor. So far we have not added any new functionality to our “sub-class” of the SalesPerson constructor, which means that it is virtually identical to the Model constructor. Let’s change that.

Example # 2A

In Example # 2A, we passed an object into the extend method of the Backbone.Model constructor. This is where we start to see some value in our efforts to sub-class this constructor. This object tells the extend method: “Hey, give me the Backbone.Model “class” but add the properties and methods that I provide in this object.

The “defaults” property is a big first step. What you are doing with that property is proving values for all of the properties that EVERY instance of the SalesPerson will constructor will have. In most cases, you will want to overwrite those properties (i.e. there is not too much use in having 700 data objects with the same “fname” of “John”. This approach makes more sense with properties like “totalSales” or “title”. These are the kinds of values that can have a default, and then on a per-item basis, when appropriate, a specific value can be provided.

Example # 2B

In Example # 2B, we have instantiated our new SalesPerson constructor three times. The first two instances: “tom” and “andy” provide all three properties that our Backbone Model expects: “fname”, “lname” and “totalSales”. But you might have noticed that the third instance: “jane”, does not provide a “totalSales” property when instantiated, which means that the default value of “$0” will be used.

Example # 3

In Example # 3, we have the full JavaScript code for our working example.

DISCLAIMER: There are a number of JavaScript anti-patterns here. I wanted to keep things simple here so please disregard the fact that there are multiple global variables, an overall lack of names-spaced methods, and no client-side templating is used.

First we have a variable named: myJsonData, which simply provides the raw data. We then have our SalesPerson constructor, which extends Backbone.Model, and has default values of “John”, “Smith” and “$0” for the properties “fnam”, “lname” and “totalSales”. We then instantiate the SalesPerson constructor four times, creating instances, which are each Backbone models (i.e. “tom”, “andy”, “jane” and “kendall”).

The variable: “isNewItem” simply provides a way to give any user-created LI elements a different appearance.

The function: “makeLi” takes a Backbone model instance and uses its “get” method to get a property value from the model. That function returns a jQuery object (i.e. an LI DOM element wrapped with jQuery).

The function: renderInitialSalesData passes our four Backbone model instances to the makeLi function, and injects them into the DOM.

Finally, we create a click-handler for the ‘#addModelSubmit” button. This handles the form submit so that the user can add a new Sales Person. On each click, the “First Name”, “Last Name” and “Total Sales” values from the form fields are passed to a new instance of a Backbone model, and then injected into the DOM.

HERE IS THE LINK FOR FULL WORKING EXAMPLE: http://examples.kevinchisholm.com/backbone/models/basics/html/part-i.html

HERE is the JAVASCRIPT: http://examples.kevinchisholm.com/backbone/models/basics/js/part-i.js

How to Demo:

When the page loads, you’ll notice that there are three items rendered in the DOM. The data for these elements comes from the global variable: myJsonData.

After page load, enter “First Name”, “Last Name” and “Total Sales” values from the form fields, and then click: “Add New Sales Person”. Each time you do so, a new LI is injected into the DOM, using whatever values you entered. Notice that for any field you leave blank, the default value defined in our model constructor is used (i.e. “John”, “Smith”, and “0”).

Summary

In this article we were introduced to Backbone.js Models. We talked about the value that they provide, and main reasons for using them. We learned how to extend the Backbone.Model constructor, add default properties to the new sub-classed constructor, and then instantiate it.

There is much much more to talk about with regards to Backbone.js models. This article barely scratched the surface, but I hope it has been a helpful introduction to the topic.

Helpful Links for Backbone.js models

http://backbonetutorials.com/what-is-a-model/

http://www.codebeerstartups.com/2012/12/3-defining-models-in-backbone-js-learning-backbone-js

Getting Started with Backbone.js Views – Part III : Event Handlers Basics

Backbone

Backbone.js LogoLearn how to set up event handlers in your Backbone.js view

In the previous two articles of this series: “Getting Started with Backbone.js Views” (Parts I & II), we learned how to set up a view and optimize it for better performance. The next logical step is event handlers.

While it may be possible that your view will not be interactive, it’s difficult to imagine a mature application that does not involve event handlers. Backbone’s approach to event handlers is a bit of a departure from your standard document.addEventListener and jQuery.click methods. Here, you will add an “events” property to the object that is passed into the Backbone.View.extend method. That “events” property is an object whose key-value pairs are sets strings comprised of an event/selector and event handler.

Example # 1A

In Example # 1A we have instantiated the MessageView constructor. Implementation details of our Backbone.js router are not at all the focus of this article, but I wanted to point out that when setting up event handlers in a Backbone view, it is important to pass an object to the view constructor. In that object, we have specified an “el” property, whose value is a jQuery DOM object. The reason for this is that it allows Backbone to properly attach our event handlers and then tear down the views DOM elements change.

Example # 1B

In Example # 1B we have added an “events” property to the object that is passed into the Backbone.View.extend method. This property is an object. In this example, that object has one property. The property name is a string that consists of two parts: the name of the event, followed by a CSS selector that identifies the DOM element to be targeted. In this case, the “click” event is specified, and the following CSS selector targets the element: “.messageView.mainMessage p”. Again, that is the key or property name. The value of that property is: “clickHandler“, the name of the function that will handle the event. This example is not very exciting. When the target element is clicked an alert shows the message: ‘I was clicked!’. We can do better.

Example # 1C

In Example # 1C, we inject the message: “I was clicked” into the DOM, a step up from the alert, but still not too sophisticated. We’ll clean this up in Example # 3.

Example # 2

In Example # 2, we have added two more properties to the “events” object: mouseover and mouseout event handlers. The purpose of this example is to illustrate that you can specify as many event handlers as you need in your “events” object.

Obtaining a Reference to the Target Element

Example # 3

In Example # 3, we have set up some functionality that is a bit of an improvement over the alert in Example # 1. Each time you click the message, timestamp is injected into the page.

You’ll notice that we are using a function named: “renderTimestamp”. This function is defined in the HTML file. Its implementation details are not particularly important. Suffice to say that when passed a jQuery DOM element object, it injects a time-stamped child element. The purpose of this is simply to demonstrate that we have real-time access to whichever DOM element is the target of an event.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 3: http://examples.kevinchisholm.com/backbone/views/basics/html/part-iii.html

How to Demo:

When the page loads, you will see the default route. If you click “message/hello” or “message/goodbye”, you’ll see our custom routes in action. In either case, the message text has a click handler attached to it.

When you click the message text, you will see a time-stamp injected into the page. No matter how many times you click the message a new time-stamp will be added. When you mouse-over any time-stamp, the background color of that time-stamp will change.

Summary

In this article we learned the basics of how to set up event handlers in a Backbone.js view. We discussed how to specify the “el” property for a view, and then create an “Events” object. We also covered how to configure multiple events, as well as how to reference the target element and manipulate it.

Helpful Links for Backbone.js View Events

http://www.codebeerstartups.com/2012/12/12-listening-to-dom-events-in-backbone-js-learning-backbone-js

http://kevinhamiltonsmith.com/backbone-js-view-dom-events-complete-list/

http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/

Getting Started with Backbone.js Views – Part II : Optimization Basics

Backbone

Backbone.js LogoiLearn how to optimize your Backbone.js view for better performance

In the first part of this series:  Getting Started with Backbone.js Views – Part I : Introduction, we learned the basics of how to implement a view in Backbone.js. Although the process of extending the Backbone.View class was quite similar to extending the Backbone.Route constructor, our code was not efficient. There are two areas to address: 1) Multiple constructor instantiations, and 2) Separation of presentation and data.

Multiple constructor instantiations

Example # 1A

In Example # 1A, we have the “message” method that is meant to handle any request to the “#/message/:text” route. While this method works as intended, we instantiate the the “MessageView” class each and every time that route is requested. There is no reason to instantiate that class more than once, and from a performance standpoint, this code is inefficient.

Example # 1B

In Example # 1B, we’ve fixed the instantiation problem by leveraging the “initialize” method. If you remember from the article: “Getting Started with Backbone.js Routes – Part IV: Configuring an Initialization Function”, the “initialize” method only executes once. This is a perfect place to handle setup tasks for views. In Example # 1B, we instantiate the “MessageView” constructor. But, instead of assigning the newly instantiated object to a variable, we assign it to “this”, which is the instance of the “AppRouter” constructor. The reason we do this is because we will need access to that instance object from the “message” method.

Then, in the “message” method, we reference that instance object twice: when setting its “options.message” property and then when calling its “render” method. Both of those actions happen every time the “#/message/:text” route is requested.

Example # 2A

In Example # 2A, we can see the other problem with our code: we mix JavaScript in with our HTML. While this does work, but it is not the most efficient way to go, and we are mixing presentation with data. We will fix this by using Handlebars.js.

Example # 2B

In Example # 2B, we have replaced our “template” method with a call to the Handlebars.compile method. We pass it our string of HTML with one small but important change: the double-curly-braces templating syntax: {{message}}. A discussion of JavaScript templating is beyond the scope of this article, but it is important to note that by using Mustache.js (or a similar templating library), we do not need to mix-in JavaScript with the HTML string we pass to the Handlebars.compile method. The double-curly-braces templating syntax: {{message}} safely retrieves the data that we reference.

Example # 3

In Example # 3, we have the full code for our working example. Visually there is nothing going on in Example # 3 that you have not seen already in an earlier article. But if you look at the page source, you’ll see that there is a dramatic difference in how we go about instantiating the MessageView constructor, as well as how we reference the data in our view’s “template” method.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 3: http://examples.kevinchisholm.com/backbone/views/basics/html/part-ii.html

How to Demo:

This example will not appear to work any differently from the previous article’s examples. The important thing to note is what is going on under the hood. Take a look at the JavaScript file for Example # 3, so you can see that we have put the techniques discussed into action.

http://examples.kevinchisholm.com/backbone/views/basics/js/part-ii.js

Summary

In this article we learned two important optimization techniques for Backbone.js views: instantiating the view constructor only once, and separating the presentation from logic. We discussed the router’s “initialize” method as the best place to instantiate our view constructor, as well as how to use the JavaScript “this” keyword to make that instance object available to other methods in the Router class. We also learned how to leverage Mustache.js for client-side templating.

Getting Started with Backbone.js Views – Part I : Introduction

Backbone

Backbone.js LogoLearn how to separate presentation from logic by leveraging Backbone.js views2

One of the main principles of MVC is the separation of presentation, data and logic. While it may be tempting to mix these concerns in order to “get it out the door”, maintaining and extending this kind of code can quickly become a nightmare. In this article, we will be introduced to Backbone.js views, which provide a tremendous amount of abstraction that keeps presentation separate from logic.

In the previous articles about Backbone routes, we learned about extending Backbone classes. Specifically, we discussed extending the Backbone.Route class. When it comes to leveraging Backbone views, the approach is exactly the same. The only difference is that we will extend the Backbone.View class.

Example # 1A

In Example # 1A, we create a variable named MessageView. This variable will become a constructor function that inherits from the Backbone.View class. We accomplish this by using the extend method of the Backbone.View class. In very much the same way that we extended the Backbone.Route class, we pass an object to the Backbone.View.extend method. In this example, the object that we passed in has two properties: “template” and “render”.

The Template Property

The “template” property tells the view “what” to render. That is, it provides the actual HTML that will be injected into the DOM. This property must be a function. Since it is a property of an object, that makes it a method. Even though it ultimately provides a string of HTML, it must be a function. So we have made it a function that returns a string of HTML.

The Render Method

The “render” property is a function, which makes it a method. This method is where you provide the code that injects the template property’s HTML into the DOM. Let’s break down the code in this method:

this.$el – “this” refers to the object, which is the instance of the MessageView variable (which is a class that we created, and it extends, or inherits from the Backbone.View class). The Backbone.View class provides a property named: “$el”, which is a jQuery object that represents the view’s parent element.

this.$el.html – Since “$el” is a jQuery object, we can use its “html” method to inject markup into the DOM.

this.template – Refers to the “template” property that we discussed above (and don’t forget: that “template” property is a method).

Example # 1B

In Example # 1B, we have the the full JS code that is used in the working example URL (below). We are leveraging what we learned about Backbone.js routes but creating a route, and configuring it for a “default” route, and our “message” route. So, when the user chooses a “message” route (e.g. “#/message/hello” or “#/message/goodbye”), our “MessageView” class is instantiated.

But this example falls short in one pretty big way: our “message” route takes a parameter from the user, but we are not making any use of that in in the view. Let’s fix this.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 1:
http://examples.kevinchisholm.com/backbone/views/basics/html/part-i-ex1.html

How to Demo:

When the page loads, you will see the message: “This is the default route”. If you click either of the other two nav links, you will see the message: “Hello from the MessageView class!”. This markup is injected into the DOM by our MessageView class.

Example # 2

In Example # 2, we made two changes:

1) we use the “text” argument passed-into the “message” method that handles the “#/message:text” route. We get this information to the view in the following line:

view.options.message = text ? text : ‘No Message Provided!’;

Details: We use a ternary operator so that if there is no text parameter passed-in, we have a default message to provide to the view.

2) We inject the message into the view’s HTML in the following line:

‘The message is: ‘ + this.options.message + ‘

Details: In the HTML string that we are returning from the view’s “template” method, we reference the “message” property of the view’s “options” object.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 2: http://examples.kevinchisholm.com/backbone/views/basics/html/part-i-ex2.html

How to Demo:

When the page loads, you will see the message: “This is the default route”. If you click either of the other two nav links, you will see the message: “The message is: hello” or “The message is: goodbye”. This is because the “message” route passes the “text” parameter to the view as the “message” property of its “options” object.

Summary

In this article, we had a brief introduction to Backbone.js views. We learned how to extend the Backbone.View class, and create the HTML that will be injected into the DOM. We also learned how to pass parameters to the view so that it can be dynamic.

Getting Started with Backbone.js Routes – Part IV: Configuring an Initialization Function

Backbone

Backbone.js LogoLearn how to configure a function that initializes your Backbone.js router

In the last few articles of this series, we have learned the basics of setting up routes in Backbone.js. We’ve discussed setting up route handlers, specifying a default route, graceful actions for corner-cases, as well as passing parameters to routes. But what about setup tasks? Sometimes you may want to execute code in preparation for your routes, but these tasks need to be completed before the routes are activated.

In this article, we will learn how to set up an initialization function that will run once, and is guaranteed to do so before the router is started.

Like much of what we have already discussed with regards to Backbone, this functionality is fairly straightforward. In the object that we pass to the Backbone.Router.Extend method, we provide an “initialize” property, which will be a method.

NOTE: In the code examples that follow, I have removed most of the implementation code so that the example will be shorter and easier to follow.

Example # 1

In Example # 1, we have added a property that is passed-into the Backbone.Route.extend method. This property is named: “initialize” and it is a method. This method will execute before the router is started. In this example, we simply fade-in a message, letting the user know that the router is initialized.

HERE IS WORKING CODE LINK FOR EXAMPLE # 1:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-iv-ex1.html

Example # 2

In Example # 2, we’ve upgraded our initialize method a bit. First, we moved all of the initialization code to the function: domSetup, just to keep the example code short and simple. There is no need to discuss the domSetup function in detail; it simply fades-in a message and sets up a few click handlers.

What interests us is the functionality that is provided here. Notice that when the page loads, if you click any of the nav links, nothing happens. This is because the router has not not been started yet. I have set a five-second timeout that delays the router’s start (the AJAX loader gif is spinning during this timeout). Once you see the green message fade-in, then all of the nav element clicks will work.

The point here was to demonstrate that if you have tasks you’d like to complete before the router is started, you can safely queue them up inside of the “initialize” method.

HERE IS WORKING CODE LINK FOR EXAMPLE # 2: http://examples.kevinchisholm.com/backbone/routes/basics/html/part-iv-ex2.html

How to Demo:

When the page loads, notice that there is an AJAX loader gif. As long as you see that AJAX loader, none of the nav element links work. Once the AJAX loader goes away and the message in a green box fades in, the nav links will work as expected. What is being demonstrated here is the fact that you can execute any setup code from the “initialize” method and then start the router manually as you wish. This is accomplished in the example code by placing all of the code that sets up the delay in the “initialize” method.

Summary

In this article, we learned how to set up an initialization function for a Backbone.js router. We learned about the “initialize” property of the object that we pass into Backbone.Router.extend, as well as how to manually start the router once our setup tasks have completed.

Getting Started with Backbone.js Routes – Part III: Passing Parameters to the Route

Backbone

Backbone.js LogoLearn how to pass values to your Backbone router in the URL

In the second part of this series: Getting Started with Backbone.js Routes – Part II: Handling Bad Requests, we learned how to handle route requests that are not configured in our router. This allows us complete control over the user experience, even when the request is one we had not anticipated. But what about parameters? How can we send the router a message? In other words, how can we pass a value in the URL that tells the application something specific?

In this article, we will learn how to pass parameters to the router, and in turn, how to access the values that are passed-in. So, for the examples that follow, we’ll imagine a very simple “order” page which allows you to specify the item you want to order in the URL. In order to keep the examples brief, I have removed any code that is not germane to the current discussion. But the full JS source code URL will be provided with each link to the working demo.

Example # 1

In Example # 1, we’ve set up a route named: “order/:item”. Up until now, our route names have been a single or hyphen-separated word. This new syntax, however, allows for more functionality.

Notice that in the route’s name, there is a colon. That colon tells Backbone that what follows is a parameter. So in this case, the actual route is “order/” and “:item” is a placeholder for whatever the user provides in that part of the URL. That value is an unknown, so we use the word “item” to represent this unknown value.

This route is handled by the method: “route”. Notice that the “route” method takes one argument: “item” (we could have named it anything, but I used “item” just to keep things consistent). This represents the parameter that was provided in the URL. So, inside of the “order” method, we now have access to that parameter.

HERE IS THE WORKING DEMO LINK FOR EXAMPLE # 1: http://examples.kevinchisholm.com/backbone/routes/basics/html/part-iii-ex1.html

HERE IS THE LINK FOR EXAMPLE # 1’s JavaScript: http://examples.kevinchisholm.com/backbone/routes/basics/js/part-iii-ex1.js

How to Demo:

Below the main nav is a brown navigation menu. As you click each menu item, notice that the URL changes. For example: “#/order/chair” or “#/order/shirt”. So, with each click, the message in the page will reflect the parameter passed in the URL after “#/order/”. You can enter whatever you like after “#/order/”, and that value will be reflected in the page’s message.

But what if the user wants to order more than one item?

Yes! This is a very logical feature to implement. It is common to specify a quantity when you order something. So, we’ll need to adjust our router so that the user can also provide the quantity in the URL in addition to the item name.

Example # 2

In Example # 2, we’ve added a new route: “order/:item/:count”. This route is also handled by the “order” method. There are two changes. This new route allows for a “count” parameter (i.e. “:count/”), and the “order” method takes a second argument: “count”.

Inside of the “order” method, we have updated the message that is injected into the DOM to include the “count” parameter, or the quantity of items to be ordered.

HERE IS THE WORKING DEMO LINK FOR EXAMPLE # 2:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-iii-ex2.html

HERE IS THE LINK FOR EXAMPLE # 1’s JavaScript:

http://examples.kevinchisholm.com/backbone/routes/basics/js/part-iii-ex2.js

How to Demo:

Below the main nav is a brown navigation menu. As you click each menu item, notice that the URL changes. For example: “#/order/chair/1” or “#/order/shirt/2”. With each click, the message in the page will reflect the parameter passed in the URL after “#/order/”, as well as the quantity (i.e. “#/order/quantity”).

But now we have a problem: If the user enters ““#/order/item” but does not specify a quantity, then the quantity will show up in the DOM as “undefined”. That’s not a good user experience, so let’s handle that exception.

Example # 3

In Example # 3, we’ve made two adjustments to our code. First, we’ve added a new route: “order/:item/”, which is handled by the “order” method. Second, we’ve added a quick check at the top of the “order” method: if (!count){count = 1}. This tells the “order” method: “hey, if the count argument is 0 or is not provided, then just make the quantity: 1).

HERE IS THE WORKING DEMO LINK FOR EXAMPLE # 3:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-iii-ex3.html

HERE IS THE LINK FOR EXAMPLE # 3’s JavaScript:

http://examples.kevinchisholm.com/backbone/routes/basics/js/part-iii-ex3.js

How to Demo:

Below the main nav is a brown navigation menu. As you click each menu item, notice that the URL changes. For example: “#/order/chair” or “#/order/shirt/”. Note that in the case of the first two links there is no quantity provided. In both cases, our “order” method sets the quantity to: 1.

Summary

In this article we learned how to pass parameters to a Backbone.js route. We learned the syntax needed to specify which part of the route request is the actual route and which part is the parameter. We discussed how to access that parameter in the function that handles the route request, how to allow for multiple parameters, and how to handle corner cases where an expected parameter is not provided.

Getting Started with Backbone.js Routes – Part II: Handling Bad Requests

Backbone

Backbone.js LogoLearn how to handle requests for a route that you have not configured

In the first part of this series: Getting Started with Backbone.js Routes – Part I: Introduction, we learned how to set up routing in a single page web application. We covered two kinds of routes: a “default” route (i.e. no route is requested), and a named route.

In this article, we will learn how to configure a Backbone router for a bad request. To be specific, a bad request would be one that you have not anticipated (i.e. you have not configured your router for that specific request). In the previous example, if you were to request a route other than “info”, there would be no error, but this is an unhandled case, and not the best user experience.

Here are two examples of unhanded exceptions from Part-I of this series:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-i.html#/bad-request

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-i.html#/another-bad-request

In both cases, the page loads, but there is no message because the router was not configured to handle the routes: “#/bad-request” and “#/another-bad-request”.

Example # 1

In Example # 1, we have updated the object passed to the Backbone.Router.extend method. There is now a third route named: “*actions”. This tells Backbone that if a request is not one of the first two specified (i.e. “” and “info”), then execute the “pageNotFound” method.

The “pageNotFound” method is similar to the other route handlers, but injects a message into the DOM that is specific to this scenario: the user has requested a route that does not exist. This way, instead of “nothing” happening, you can present very specific content to the user.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 1: http://examples.kevinchisholm.com/backbone/routes/basics/html/part-ii.html

How to Demo:

When the page loads, you will see the message: “This is the default route”, and if you click the “info” link, you will see the message: This is the “Info” page. But if you click the link: “Bad request”, you will see the message: “Sorry, the page you requested was not found”. The reason for this is that there is no route configured for: “#/bad-request”. In fact, no matter what you request, unless that route request is: “” or “info”, then you will see the message: “Sorry, the page you requested was not found”

Here are a few examples:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-ii.html#/no-route-here

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-ii.html#/no-route

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-ii.html#/not-handled

When you click any of the links above, you will still get the message: “Sorry, the page you requested was not found”.

Summary

In this article, we learned how to configure our Backbone router to handle bad requests. We discussed the “*actions” property of the “routes” object, and how to make sure it is the last property specified in that object. We also set up a function to be executed whenever a bad route request is made.

Getting Started with Backbone.js Routes – Part I: Introduction

Backbone

Backbone.js LogoLearn the simple yet powerful syntax for setting up routing in your Backbone.js single page application

Routes are one of the most important aspects of any single page application. Routes allow you to intercept browser address changes and act upon them accordingly. As per the moniker “single page application” suggests, after the completion of the initial page load, you never want the user to endure a round-trip to the server.

Backbone.js provides simple yet powerful abstraction for routing. In this series of articles, we will explore the core syntax and features that allow you to build-out routing for your single page application.

Extending Backbone.Router

Extending classes is an important topic to quickly review. In Backbone.js, when you want to create a router, you first need to extend the Router class. To be more specific, “Router()” is a JavaScript constructor function that is a property of the “Backbone” object. Extending the Router class allows you to leverage all of the existing functionality while adding more of your own. When you extend the Router class, you are creating a new constructor that inherits from the “Backbone.Router”. Once you have extended the Router class, you’ll then need to instantiate your new constructor.

Example # 1A

Example # 1B

In example # 1A, we create a new variable named: “AppRouter”, and set it to the return value of Backbone.Router’s “extend” method. The “extend” method allows you to create a class that inherits from another and is available in a number of Backbone objects. In this case, our class does not do too much, so we have a bit more work to do.

In example # 1B, notice that an object is being passed to the extend method. This object is empty, and our AppRouter class still does not offer much value. The main points to remember as we move forward are:

You create a router by extending the Backbone.Router class, using the “extend” method
The extend method requires an object as its sole argument
The result of extending the Backbone.Router class is a new class (or constructor), which will need to be instantiated

NOTE: Our variable begins with a capital “A” (i.e. “AppRouter”). This is not required but it is recommended because in JavaScript (as well as other languages), classes usually have an initial capital letter in their name.

Example # 2

In Example # 2, we have added quite a bit of functionality to the object that is passed into the extend method. This object has three properties: “routes”, “home”, and “info”.

The “routes” property is critical. This property is an object. The properties of the object are the routes that we want to map. In this case, there are two:

  • “” – When no route is requested, map to “defaultRoute”
  • “into” – When an “info” route is requested, map to “info”

But, what are “home” and “info”? Well, they are the other two two properties of the object passed to the extend method, and they are method (i.e. they are properties whose value is a function). So, when no route is requested, Backbone will execute the “defaultRoute” method, and when the “info” route is requested, the “info” method will be executed.

This example is very basic; you are not likely to create a single page application with only two routes. What is important to remember is that as you build out your application, this is a pattern you will follow:

  • You extend the Backbone.Router class by passing an object to the extend method
  • In the object you pass to the extend method, you provide a “routes” property
  • The “routes” property is an object that has a set of properties that map to methods
  • The methods you map to are functions that handle the route request

There are still a couple of steps left in order to get our new Router to a working state.

Example # 3

In Example # 3, we take two further steps that are needed in order to get our Backbone.js router to a working state:

  1. We instantiate our AppRouter class
  2. We call Backbone.history.start(); from the jQuery document.ready method.

The first step is required because even though we extended the Backbone.Route class, we need to instantiate the new class (or constructor) that we created. A detailed discussion of the Backbone.history object and its “start” method is beyond the scope of this article, but suffice to say that this step is needed in order to get the routing process started. Wrapping it in a call to jQuery’s document.ready method is generally a good idea so that you can be sure that the routing does not start until the DOM is ready.

HERE IS THE LINK TO THIS ARTICLE’S WORKING EXAMPLE:

http://examples.kevinchisholm.com/backbone/routes/basics/html/part-i.html

How to Demo:

Click the “Home” and “Info” links in the page’s navigation menu. As you do this, look closely at the browser’s address bar. You’ll see that “#/” and “#/info” are appended to the address. These are routes. The code that we worked on in this article intercepts these route requests and prevents the page from making a request to the server located at: “http://examples.kevinchisholm.com/”. Accordingly, messages that are results of the functions we execute upon each route request are rendered in the DOM.

Details

When the page loads, you will see the following message: “This is the default route”.The reason for this is that when we extended Backbone.Route, we specified that if no route was requested, the “defaultRoute” method should execute. If you click the “Info” menu item, you’ll see the message: This is the “Info” page. This is because we specified that when the “info” route is requested, the “info” method should execute.

Summary

In this article, we were introduced to Backbone’s routing feature. We learned about extending classes, and specifically, the syntax needed to create a constructor function that inherits from Backbone.Router. We discussed the steps needed to configure our router so that a number of possible routes can be anticipated and acted upon accordingly.

Helpful Links for Routing in Backbone.js

http://backbonejs.org/#Router

http://backbonetutorials.com/what-is-a-router/

http://www.codebeerstartups.com/2013/01/routers-in-backbone-js-learning-backbone-js