Angular 1.x Concepts In Aurelia

If you’re like me, you’ve worked with Angular a lot or you are currently working with Angular and over time you have grown accustomed to its very concepts; controllers, directives, factories, providers and services. In Aurelia those concepts can exist, but not in the way you think.

If you’re thinking of porting over an Angular 1.x application to Aurelia, below we will touch upon various concepts to make the transition as easy and seamless as possible.

There will not be any code comparison, this article assumes you have opted to choose Aurelia for your next or current application and you come from an Angular background, wanting to understand new concepts.

Directives

One of the things I really hated about Angular is the confusing directive syntax. A directive can be both an attribute or element. In Aurelia they’re not called directives, we have two separate types we can choose: Custom Attributes or Custom Elements.

Factories/Providers/Services

In Angular we have all of these confusing ways of creating singletons; providers, factories, services and resources. In Aurelia a ViewModel/class is presumed to be singleton by default. We even have the option of declaring it as transient as well. Read more here about Aurelia’s dependency injection.

Controllers

Nope. There are no controllers in Aurelia. All you have is a ViewModel that is rendered either by the router or some other part of your application. Aurelia is not an MVC framework.

Filters

In Aurelia the concept of filters does exist, except they’re more aptly named value converters. As you can see here the syntax is almost the same. Porting over Angular filters to Aurelia should be a breeze.

Binding & Templating

If you’re porting an Angular application, this part will be the most important. Understanding how Aurelia deals with displaying and binding to values in a view opposed to Angular.

Templating

Keeping inline with ECMAScript 2015 templating, all Aurelia HTML template views require <template></template> tags to properly acknowledge themselves as views.

Expressions & Strings

In Angular we used double curly braces to display values and perform expressions inside of our HTML. Because Aurelia utilises ECMAScript 2015/2016 specifications, we can use string interpolation instead.

In most cases simply retraining your brain to use ${} instead of {{}} is all you need to remember when working with Aurelia. You can read more about string interpolation via the official Australia documentation.

Language

In Angular we have; ngClass, ngHide, ngInclude, ngRepeat, ngSrc and so on. In Aurelia there are counterparts to these features found in Angular.

  • ngClassclass="${myClassString}"
  • ngClickclick.trigger="function()" or click.delegate="function()"
  • ngHideshow.bind=""
  • ngInclude<require from=""></require>
  • ngRepeatrepeat.for="item of items"
  • ngSrcsrc.bind=""

Databinding

In Angular we had the likes of ngModel, ngValue and other bindings for working with form input values. In Aurelia we still have this concept, the API however is easy to understand use.

One Way Binding

By default .bind will assume a “one-way” binding relationship for all attributes, with exception of form element values which use “two-way” binding by default.

In Angular to achieve one-way binding, we need to use something like ngValue to prevent a two way relationship or ngChange

One Time Binding

A one-time binding means that a value is not bound at all, there is no observation happening. The value is just printed into the page as is and any future changes will not update the value.

In Angular we have the confusing {{::myVar}} and in Aurelia we have a more verbose value.one-way=""

Two Way Binding

All form elements in Aurelia are presumed to be “two-way” bindings. Any non form elements are presumed to be “one-way” bindings by default. However, given Aurelia offers a verbose way of binding, we can simply use: value.two-way="" and we have two way binding.

Conclusion

As you can see Aurelia simplifies your workflow. From working with databinding, to templating and custom expressions. The lack of abstraction means you spend less time scratching your head and more time coding.

If something did not make sense or I missed an important aspect of Angular that should have its equivalent covered in Aurelia, leave a comment below or drop me an email.

Migrating AngularJS Directives To Aurelia – Part I: Custom Elements

So you’ve decided it’s time to join the future and port your existing Angular application to Aurelia. Your first port of call was probably the documentation and chances are you probably got confused, because Aurelia lacks the concept of a “directive” – don’t be discouraged my friend, there is light at the end of the tunnel.

The concept of directives do exist in Aurelia, however they go by the names: Custom Attribute and Custom Element. In Angular 1.x, a directive can both be a custom attribute and a custom element. It is a confusing concept that fortunately has been removed in Angular 2.

If you’re looking to jump the fence to greener pastures into Aurelia land, then this article will show you how to port over Angular directives to Aurelia.

Part I: Custom Elements

In AngularJS 1.x a custom element is created using what is called a directive. In Aurelia a directive is either a custom element or custom attribute. The terminology is different, Aurelia’s is more concise and explanatory in comparison to Angular’s use of the word directive.

In this section we are going to create a custom HTML element which is used using the <person> HTML element. We will also have the ability to pass through an object of data which the custom element will use to populate itself.

Angular

As we discussed earlier, custom elements in Angular 1.x are directives with the restrict property set to ‘E’ — lets proceed.

Create the directive

Firstly, lets define our custom element in a file we will aptly call person-directive.js – this will be responsible for setting up what type of directive we are creating and what data it can accept.

angular.module('myApp', [])
    .directive('person', function() {
        return {
            restrict: 'E',
            scope: {
                person: '=data'
            },
            templateUrl: 'person-directive.html'
        }
    });

Create the directive view template

Although Angular directives allow us to create inline templates, to keep in the spirit of doing things the way we can do them in Aurelia, we will be creating a separate view template called person-directive.html

<div class="person">
    <div>Name: {{person.name}}, Location: {{person.location}}</div>
</div>

Using our directive

As you can see we have our custom element created. We can reference it using <person> and it if the passed in data matches what we expect in the view, we will see their name and location.

Create a controller (aka ViewModel)

This controller handles passing through data to a specific part of our application. You might access this controller through a route called “/people” if this were a real application. In this controller we define some mock data, an array of people objects.

angular.module('myApp', [])
    .controller('PersonController', function($scope) {
        $scope.people = [
            {name: 'Dwayne', location: 'Australia'},
            {name: 'Rob', location: 'USA'},
            {name: 'Max', location: 'France'}
        ];
    });
Create a controller view (aka View template)

This might not reflect how you would render the above controller in the real world, but for our purposes it will work just fine. Presumably here we would be including Angular itself from a CDN, our directive and controllers.

<html>
    <head>
        <title>PeopleApp</title>
    </head>
    <body>
        <div ng-app="myApp" ng-controller="PersonController">
            <ul>
                <li ng-repeat="person in people">
                    <person data="person"></person>
                </li>
            </ul>
        </div>
    </body>
</html>

As you can see, Angular is a horrible mess. Some concepts kind of make sense, especially if you’re drunk or high. But honestly, concepts such as $scope and restrict are constant sources of confusion and frustration for newcomers.

Aurelia

Now we are going to create the same custom element within Aurelia. In Aurelia custom elements are referred to as custom elements, so no confusing double-meaning directive terminology here.

One of the first things you might notice is we have considerably less code in comparison to the above example.

Create the custom element

The below example is a little more verbose. We can also specify an element as a custom element or attribute by naming the class PersonCustomElement and remove the @customElement decorator if we wanted to shave off an extra line of code.

We are assuming this file is called person-element.js (this is important as we will import this later using this name).

import {customElement, bindable, bindingMode} from 'aurelia-framework';

@customElement('person')
@bindable({ name: 'person', attribute: 'data', defaultBindingMode: bindingMode.twoWay})
export class Person {
}

Create the custom element view template

You might have noticed that we didn’t specify a view template name above. Because Aurelia favours a convention based approach, it assumes a ViewModel has a paired View of the name filename, just with a .html extension instead.

Using the above mentioned convention, we call this file person-element.html and leave it to Aurelia to pair them up.

<template>
    <div class="person">
        <div>Name: ${person.name}, Location: ${person.location}</div>
    </div>
</template>

Using our custom element

We use our custom element the same way we used it above in our Angular example. We still reference our element using <person> inside of our View. This is the only comparable feature between Angular and Aurelia in how something works.

Create a ViewModel (aka controller)

In Aurelia the concept of a controller does not exist. Everything utilises ViewModel’s which are presumed to be paired with a View template (using default conventions). In our case we’ll just call it my-view.js

export class MyView {
    people = [
        {name: 'Dwayne', location: 'Australia'},
        {name: 'Rob', location: 'USA'},
        {name: 'Max', location: 'France'}
    ];
}
Create a View (aka controller template)
<template>
    <require from="./person-element"></require>

    <ul>
        <li repeat.for="person of people">
            <person data.bind="person"></person>
        </li>
    </ul>
</template>

Conclusion

The difference is night and day between the two. As you can see porting over Angular directives to Aurelia is quite easy and considerably less code. I am sure there are ways to make my Angular examples smaller, but the way that I wrote them is probably how 98% of all Angular developers would create them.

In another post and conclusive part II, we will be looking at moving over Angular directives being used as custom attributes.

The Death of AngularJS

Update 28/1/2016: This post was about Angular 1, it was published well before Angular 2 was even near ready for beta release. A bit has changed since then, but my thoughts on Angular in this post have not.

For quite a long time developers have been using AngularJS. Coming at a time when the alternatives were the likes of Backbone.js (while powerful in its own right), which just didn’t tick all of the boxes a modern web application needs ticked, we thought we had reached developer nirvana.

We got two-way data binding, controllers, directives and templating syntax. For a good while things were peachy, the sun was shining and everyone was sipping from the golden chalice of AngularJS kool-aid. We put it on t-shirts, wrote books, online training courses, bumper stickers and they sold baby, they sold.

As modern web application development evolves at a steady pace, the number of Javascript frameworks out there to choose from is staggering. It seems everyone has a Javascript framework, 10 new Javascript frameworks will probably come out by the time you finish reading this article.

While AngularJS is far from dead, its eventual demise is coming. A slew of core problems with the framework, more notably dirty-checking and transclusion was enough to rally the detractors to write blog posts about why you shouldn’t use AngularJS. They were all right in their own special way, but some were missing the point.

Not too long ago there was no viable alternative to AngularJS. I am not just talking about feature-set or community participation, I am talking about the lack of actual backing by anyone other than a few neck-beards in their basements contributing to their beloved open source project.

While there are some great Javascript frameworks out there, not many can guarantee with almost absolute certainty that they’ll be around tomorrow (not even Angular could do that, but the Google backing was reassuring).

This is where AngularJS succeeded. The everyday developer loved it, people were using it with WordPress and pretty much anything they could stuff Angular into. And then the enterprise started using it, all of a sudden you were seeing listings for local council and government jobs that listed AngularJS as a desired skill.

But why? If other choices were out there, why did Angular succeed? Was it because it was the first one out of the gate to offer almost everything you would find in a server-side framework or was it the fact it was backed by Google? In part it was both. But there was one other aspect of Angular that made it appealing.

I think it is safe to say that many took comfort in the fact that Google was behind Angular and if Google was behind it, then it must be good. This kind of trust in Google surprises me given their poor track record sunsetting a whole lot of products with their backing, more notably Google Reader.

Instead of trying to replace HTML, Google strengthened it. Decorating HTML with custom attributes, elements and control directives was a hit with everyone. Instead of having to create nested objects in a Javascript file, you were working in HTML and then using said decorations to make things happen in Javascript when you were ready.

It was Lego (AngularJS) vs Meccano (every other framework).

While the disdain for Angular was strong, the love that people had for it remained the strongest. For every hate-piece on Angular, there was a retort that would follow soon after.

The fighters and lovers were on equal footing, kind of like a war. One side spews propaganda and the other side does their best to dispel it: the PHP language is all too familiar with this ugly side of development.

“This ain’t a scene, it’s a god damn arms race” – Fall Out Boy.

When things go wrong

A little while ago talk of Angular 2.0 came about. Instead of it being a natural evolution of the framework, it was revealed that it would be a complete rewrite. The backwards compatibility, transclusion and most hated of them all: dirty-checking would either be removed or rewritten in a more efficient manner in 2.0.

But the Angular team did something that no open source project in a highly competitive battlefield should do: they announced a new version of their highly popular framework that would have no backwards compatibility with the 1.x branch and that there would be no upgrade path whatsoever.

gasp

When the Angular team announced this, you could practically hear a record skip right across the Internet. The concern started relatively contained with the Hacker News comments section and then it escaped, soon everyone was writing blog posts defending the new syntax and lack of backwards compatibility, but many were decrying such a move.

Not only did they announce there would be no backwards compatibility or upgrade path, they also revealed a controversial new syntax for decorating your HTML markup.

Why were people so angry? The Angular team announced they would be addressing all of the shortcomings in version 2.0, that transclusion you hate so much? Gone. Dirty-checking? Completely rewritten to be more memory efficient and use browser object-observe when supported.

Even though at its core 2.0 would arguably be a much better successor to Angular 1.x, removing a large chunk of backwards compatibility and starting from a clean slate, for a version 2.0 the Angular team shocked by changing too much, too soon.

It all comes down to the fact that it is a universally accepted downside of Angular that it has a steep learning curve. The basics of Angular not so much, but the more nitty gritty aspects of the framework were arguably harder to learn due to confusing documentation and confusing blog posts that would go against some of the things the documentation would tell you to do.

You could say that AngularJS 2.0 was a message: every developer that had spent their time learning the framework were being told mostly everything they have learned would be invalidated in possibly 12 months time when 2.0 is released.

It’s like learning French only to discover that in 12 months time that all French speaking nations would be switching to Italian, sure there might be some similarities but it is a completely new language you have to learn.

The biggest controversial aspect of Angular 2.0 was not just the lack of upgrade path, it was the new syntax which looked ugly. There were concerns it would also throw HTML validation (some people still run their sites through the W3C validator surprisingly).

It would take a little bit of time after for the Angular team to sit back and realise they had made a big mistake. Their stubbornness had already caused Rob Eisenberg (of Durandal fame) to abandon the Angular 2.0 team and build a successor to Durandal in the form of Aurelia. While the Angular team might not have realised it, losing Rob was actually a big blow to the project.

Now we are seeing Angular 2.0 components being ported back to 1.4 and while the 1.x branch will continue to be supported for a little while, the damage has been done. Even though there will now be an upgrade path (sort of), it is too little, too late.

Death is near

Even though AngularJS 2.0 has yet to be released, many have abandoned it already. There are a few great choices out there for starting your next Javascript framework like Aurelia or React.js. Those still using AngularJS are supporting legacy applications or junior developers completely unaware of the changes taking place around this framework and the framework space in general.

Having said that: not everybody will abandon AngularJS and support for the 1.x branch will continue for some time. However, once 2.0 lands, it would make very little sense to use the older and more troublesome 1.x branch.

While AngularJS 1.x will remain popular for some time yet, make no mistake React.js alone in its relatively short lifespan has taken an axe to Angular’s market share quite significantly and we will see those effects ten fold when Angular 2.0 is released.

This coupled with other frameworks like Aurelia and EmberJS which has seen a massive uptake by developers, Angular is not the only kid in the playground anymore.

Angular is not going anywhere in the interim, but I think there is now enough competition in the space that simply being backed by Google is not enough to convince developers to stay and trust their decisions are the right ones.

Is It Still Worth Learning Angular 1.x?

As ES6 edges closer to evergreen browser support by the estimated mid–2015, many are wondering given the MASSIVE inevitable API breaking changes in Angular 2.0 if it is worth learning the current version of Angular (1.3 at the time of writing this).

The fear around Angular 2.0 I think is overblown. While it will be a complete rewrite, your newfound Angular 1.x skills aren’t just going to go to waste, especially considering Angular 2.0 might not even be released until late 2015/early 2016.

At the moment the only choice you have is to either use AngularJS as it currently stands or wait until late this year/early next year (if you have that luxury) to build your application using 2.0 but risk running into inevitable early adoption issues.

The 1.x branch isn’t going anywhere… yet

People are panicking, but Angular’s version 1 branch will continue to work for years to come. Just because a new version comes out doesn’t mean you need to start using it right away. The existing code doesn’t just stop working.

The Angular team haven’t abandoned the version 1 branch in light of the impending 2.0 release either. Version 1.4 is due out shortly and it comes with a whole bunch of new changes and improvements; forms, internationalisation fixes, tweaks to the $http client and more.

It appears that the 1.x branch will have at least a couple of years worth of updates and support which should be more than enough for developers to migrate over to the new version. And even then, you don’t have to upgrade. The old version will keep on working fine.

Angular 1.x is stable

When the new version of Angular hits, it would be unfair to expect a battle tested and stable version straight out the gate (especially considering it is a complete rewrite). While some existing problems might be fixed, new ones will take their place.

The benefit of the current version of AngularJS is that it is relatively stable. We are aware of mostly every single caveat that it has (like too many watchers slowing down your app).

Some people still support IE8

Not all of us have the luxury of being able to write-off Internet Explorer 8. I recently worked on a large project that used Angular 1.2 because of the need to support IE8.

Version 1.3 and onwards dropped support for IE8 and presumably, Angular 2.0 is definitely not going to support IE8 due to most ES6 functionality needing IE9+ for the transpiled ES5 output.

This means we are going to have a subset of people for potentially the next few years using Angular 1.2 because of the need to use IE8.

Conclusion

It is definitely worth learning AngularJS pre-version 2.0 rewrite. Even though version 2.0 is going to heavily use ECMAScript 6 features and be a different framework, your newly learned skills won’t be immediately thrown out the window.

Some of the concepts in the current version of Angular could make their way into the new version, albeit in a different form due to a new syntax, you should be able to spot differences easier after learning Angular 1.x.

As it stands you probably have another 2 years before you need to consider switching over to the 2.0 branch. Which in development land is a VERY long time for anything related to the front-end.

Increasing AngularJS Performance By Debouncing Your ng-model Updates

One of the biggest bottlenecks in Angular 1.x is the $digest cycle. Essentially what the $digest cycle does is keeps track of two-way bindings, watchers and other parts of your Angular application that can be updated.

For example if you have a text field using an ng-model, whenever you type in a value into this field, it will trigger a $digest cycle causing Angular to update all watchers and bindings in the app to see if anything has changed. This is because of the lack of object.observe() in ECMAScript 5 (although it is in ECMAScript 2016 (ES7) and planned for Angular 2.0).

In version 1.3 of Angular, a native debounce feature was introduced which can be supplied to ngModelOptions.

Debounce, what?

What is a debounce you say? Essentially it is a delay which says, “Wait X amount of time and then do this action if an action is not already in progress” so in the instance of waiting for typing in a field for an email for example, you might want to put in a delay of 300 milliseconds so if a user stops typing and doesn’t resume within 300 milliseconds, an action will be fired which will trigger a $digest cycle.

As can be seen in the above linked Angular documentation on ngModelOptions there are a few Plunker examples showing debounce and selective updates on ng-model.

<div ng-controller="ExampleController">
  <form name="userForm">
    Name:
    <input type="text" name="userName"
           ng-model="user.name"
           ng-model-options="{ debounce: 1000 }" />
    <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button><br />
  </form>
  <pre>user.name = </pre>
</div>

The above example taken from the Angular documentation shows that we are setting a debounce value of 1000 milliseconds which is 1 second. This is a considerable delay, but will prevent the input from repeatedly thrashing ng-model with many $digest cycles.

By using debounce on your input fields and anywhere else where an instant update is not required, you can increase the performance of your Angular apps quite substantially. Not only can you delay by time, but you can also delay when the action gets triggered. If you don’t want to update your ng-model on every keystroke, you can also update on blur as well.

A word of warning

If you set your debounce values too high, users will perceive your app as slow because you are artificially delaying the response and triggering of actions within your Angular application.

In most cases, a delay of 250 to 350 is acceptable and will not offer any overly noticeable slowness in your applications. Unless you need to set a higher value for whatever reason, keeping your debounce values below 350 will ensure your app is not only performant but still responsive.

AngularJS: How To Call A Controller From Another Controller

In AngularJS when it comes to communicating between controllers, one would naturally assume to reference another controller you can simply inject it into another controller and call its methods: however, you cannot do that.

Method 1: Shared service

One such method of communicating and sharing methods betweens multiple controllers is a shared service. Here you might put in a method for closing a overlay or redirecting the browser somewhere or checking the state and value of a variable.

The following example assumes you have created a service called “myService” and you have a method called updateVal and getVal for getting and setting values.

var myModule = angular.module('myapp', []);

myModule.controller('myController', ['$scope', 'myService', function ($scope, myService) {
    myService.updateVal('name', 'Dwayne');
}]);

myModule.controller('otherController', ['$scope', 'myService', function ($scope, myService) {
    if (myService.getVal('name') === 'Dwayne') {
        alert('The name is ' + myService.getVal('name'));
     } else {
         alert('There is no Dwayne');
     }
}]);

This is my preferred approach for sharing data and methods between controllers for a number of reasons; it makes things cleaner, it keeps logic separate from your controllers and above all: it makes things easier to test.

Method 2: Events

In some cases, events can be a lot cleaner than using a separate service. Triggering an event say for example when you open up an overlay, close it or perform some action you want to inform other controllers about can be done emitting an event on $scope.

var myModule = angular.module('myapp', []);

myModule.controller('myController', ['$scope', function ($scope) {
    $scope.$on('profile-updated', function(event, profileObj) {
        // profileObj contains; name, country and email from emitted event
    });
}]);

myModule.controller('otherController', ['$scope', function ($scope) {
    $scope.$emit('profile-updated', {
        name: 'Dwayne',
        country: 'Australia',
        email: 'somedude@example.com'
    });
}]);

Conclusion

Pick whichever feels right. I personally prefer method 1 because as I mentioned, it is testable, it is cleaner and keeps things separate. But using events also have their advantages as well.

AngularJS: What’s The Deal With $scope.$apply, Yo?

Chances are if you have been using AngularJS for a little while that you have come across $scope.$apply() at some point, whether it be your own code or someone else’s. What the heck is $scope.$apply() and why should you care?

To understand why we have $scope.$apply we have to understand that Javascript is turned based. When you write your Javascript code, it does not run all at once, code is run in blocks. So it is possible when you change a value within Angular and a $digest cycle has already been run, your changes will not be seen.

When you make a change outside of a non-Angular method, so a native DOM event or method in a third party library like jQuery, Angular does not know anything changed and as such, will not acknowledge anything has changed. All $scope.$apply does is basically says: “Hey Angular, a value changed bro, thought you should know, so you can tell your listener homies about it

When you use $scope.$apply it will trigger a $digest cycle which ties into two-way binding which AngularJS uses quite heavily. Effectively $scope.$apply is a wrapper around $digest. Incorrect use of $apply can result in a “digest already in progress” error which means you tried using $apply when a $digest is already running.

Actions in AngularJS that trigger a $digest can include; in-built Angular directives like ng-repeat, ng-hide, ng-show, ng-click and even $http calls. If you try using $scope.$apply within one of these calls or even within a $timeout, you will get issues.

You should ideally only ever use $digest or $apply inside of an asynchronous call to let Angular know when you have made some changes as the official wiki details. And you should never use $apply or $digest within a controller, only within directives and services.

A classic example that does the runs is using a setTimeout (you would ideally use a $timeout but for example sakes):

setTimeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 3000);

In the above example, after 3 seconds, the timeout function will resolve itself and set the $scope variable “message” to ‘Timeout called!’ because we are updating code from a non-Angular method, we need to call $apply to tell Angular about the changes.

In a nutshell $scope.$apply tells Angular and any watchers that values have been changed and to go back and check if there are any new values. This keeps things within the Angular context regardless of how you made a change, like in a DOM event, jQuery method, etc.

Constants & Values: Global Variables In AngularJS… The Right Way

The subject of global variables in most languages is enough to bring the most passionate code junkies out of the woodwork ready to debate and bite off your feet for even entertaining the thought.

The reality is in a framework like AngularJS globals are warranted at times, but only if you implement globals the Angular way. But not globals in the way you know.

Constants and values

Out of the box, AngularJS supports global constants and values. Obviously constants are read only pieces of data and values are pieces of data that can change at any time, anywhere.

However, it is worth pointing out that setting a constant to have an object of properties and values means you can modify those properties inside of the constant because that is how Javascript works. We will get into this a little later in the examples.

Values like the application name, version and even URL’s to various endpoints like API’s generally should never change within your application and are always constant, so therefore, they should be constants.

Values that can be changed such as storing a count of users online where it can go up and down, would be a better use-case for values as you need to be able to write and read them anywhere in your application or a specific service/provider. Storing session data such as an email, profile ID and names is also another good candidate for values.

It is worth pointing out that constants and values can store more than single or multiple keyed values in objects, you can also use functions and other various methods, but for the sake of keeping things easy and clean, stick to single values and objects.

The benefits

So what are the benefits of using Angular’s constants and values? The fact they are versatile and allow not only storing single values, but also being able to store objects of data and inject them into services, etc all without polluting the global namespace.

They are also testable as they work like any other service and can be injected into directives, controllers and services. It is worth pointing out that constants can be injected everywhere and values are limited to controllers, directives and services.

You can for example inject constants into module.config, but values cannot be injected into a config function call.

Examples

Enough rambling, here are some examples of setting constants and values, and then accessing them from various parts of your application all without having to create one single dirty Javascript variable.

Constants

Constants and values are pretty much the same with a couple of differences. As mentioned earlier, constants can be injected anywhere including configuration calls. So when you call module.config and set up states or other runtime settings you can inject constant values, but not values.

Also, as mentioned earlier, there is one caveat with constants that can cause them to be editable and that is using anything other than a primitive. Values other than primitives are treated as objects. When using objects with a constant they can be modified, which for a constant makes no semantic sense whatsoever.

This is not to say you can NOT use an object inside of a constant, as long as you or other developers do not modify any of the values contained therein. It is best to stick with values below if you want to modify values.

// Storing a single constant value
var app = angular.module(‘myApp’, []);

app.constant(‘appName’, ‘My App’);

// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘appName’, function TestCtrl(appName) {
    console.log(appName);
}]);
// Storing multiple constant values inside of an object
// Keep in mind the values in the object mean they can be modified
// Which makes no sense for a constant, use wisely if you do this
var app = angular.module(‘myApp’, []);

app.constant(‘config’, {
    appName: ‘My App’,
    appVersion: 2.0,
    apiUrl: ‘http://www.google.com?api’
});

// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘config’, function TestCtrl(config) {
    console.log(config);
    console.log(‘App Name’, config.appName);
    console.log(‘App Name’, config.appVersion);
}]);

Values

Constants and values are pretty much the same, but remember they are for storing pieces of data that are temporary, they can change anywhere, any time. Even though constants can work the same as values, only values should be modifiable. You should not use an object inside of a constant in the place of what should be a value instead.

You will notice the examples are basically the same as constants, the syntax is the same with exception of the fact that we are setting values as well as reading them.

// Storing a single value
var app = angular.module(‘myApp’, []);

app.value(‘usersOnline’, 0);

// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘usersOnline’, function TestCtrl(usersOnline) {
    console.log(usersOnline);
    usersOnline = 15;
    console.log(usersOnline);
}]);
// Storing multiple values inside of an object
var app = angular.module(‘myApp’, []);

app.value(‘user’, {
    firstName: ’‘,
    lastName: ’‘,
    email: ’’
});

// Now we inject our constant value into a test controller
// Values will be empty
app.controller(‘TestCtrl’, [‘user’, function TestCtrl(user) {
    console.log(user);
    console.log(‘First name: ’, user.firstName);
    console.log(‘Last name: ’, user.lastName);
    console.log(‘Email: ’, user.email);
}]);
// Storing multiple values inside of an object
var app = angular.module(‘myApp’, []);

app.value(‘user’, {
    firstName: ’‘,
    lastName: ’‘,
    email: ’’
});

// Now we inject our constant value into a test controller
// Values will be populated inside of controller
app.controller(‘TestCtrl’, [‘$scope’, ‘user’, function TestCtrl($scope, user) {
    user.firstName = ‘Dwayne’;
    user.lastName = ‘Charrington’;
    user.email = ‘dwayne@ilikekillnerds.com’;

    console.log(user); 
    console.log('First name: ', user.firstName); 
    console.log('Last name: ', user.lastName); 
    console.log('Email: ', user.email); 

    // Pass the user values through to the view 
    $scope.user = user;
}]);

Conclusion

Constants are great for values that never change. If you need to access values within config function calls to configure routes or anything else when your application first starts, constants are what you should use.

Values are great for pieces of data that can and will change. As shown above user data or anything else where you simply want to keep a reference to a changing value stored globally without creating a messy global variable.

When To Use AngularJS And When You Should Use ReactJS

In the front-end framework race there are many contenders, but the one that stands out from most is AngularJS which is supported by Google. It simplifies the process of complicated and simple application flow, but when it comes to rendering many items (especially using ng-repeat) you soon notice AngularJS struggles.

I will not bother posting my own benchmarks, as there is pretty conclusive proof out there you can find via a Google search. I love Angular, do not get me wrong, but it sucks for rendering lots of UI items, like for example a large catalogue of products comprised of; titles, descriptions, star ratings and a thumbnail image.

All preexisting solutions out there to combat the issue of many items and bad performance in an AngularJS application are merely hacks to get around what is a shortcoming of the framework itself. You could argue one-way binding, but you lose the ability to have dynamic items, pagination and more, but each solution has its tradeoffs which for some, might be too much of a tradeoff to implement.

This is where ReactJS comes into the fray. While AngularJS aims to be MVC (Module View Controller) ReactJS likes to call itself the “V” in MVC. This means you can use ReactJS in the form of an AngularJS directive to render items and keep track of their state.

The issue with AngularJS is that it works on the premise of directly watching and modifying the DOM (using dirty checking). In the instance of a large amount of “ng-repeat” items, if you have watchers on potentially thousands of elements in the page, it does not take a computer scientist to work out what will happen: performance will suffer.

The premise of ReactJS is something it calls a virtual DOM. This is an in-memory representation of your DOM, when a change is made, it is made in memory and the DOM is subsequently updated when needed.

Rather than checking the DOM for what has changed and what needs to be updated, all of this is handled in memory which results in blazingly fast mass updates and changes to the DOM because the heavy work is being off-lifted outside of the page itself.

I like to think of ReactJS as a NoSQL database for the DOM. While the underlying codebase of ReactJS is anything but simple, the premise of ReactJS is simple enough to know it is effectively a key/value store for the DOM (only you’re not querying elements, but rather the way it keeps the DOM structure in memory and checks what has changed). It is incredibly easy to learn and pick up, the learning curve is a whole lot more simpler than AngularJS is to learn.

Controversy…

Now some people would argue that you should not mix the two and in an ideal world, that is probably a good recommendation. However, recently whilst working on a large-scale project in AngularJS, the use of ReactJS was warranted because it was better than the alternative of poor browser performance and a bad user experience.

The beautiful thing about ReactJS is that it does not care what front-end framework you are using. All it cares about is rendering HTML markup that has been Reactified and created within the React component itself. This allows you to use the features in AngularJS like services and factories and effectively replace “ng-repeat” with ReactJS instead.

If I were to start a new project tomorrow, I would definitely just use ReactJS in combination with Flux to build my application without AngularJS (as far as I could feasibly do so). You could effectively build a Facebook like web application using Node.js as the server and ReactJS as the front-end.

However, the reality is, not all of us developers have the luxury of being able to throw existing code away and start again from scratch, especially in a large organisation, it just does not make any sense. But if you are stuck trying to optimise a preexisting application in AngularJS this is a good solution that gives you the view rendering power of ReactJS and the versatility of AngularJS.

Angular: The lovable quirky beast

While I am a big fan of Angular, it does have some performance issues and various quirks. If you know what they are and how to work around them, Angular can be performant and great. The biggest issue is two-way binding which basically allows a value to be tracked and update via a $digest.cycle() called every time something happens.

Because ECMAScript 5 does not support watching values out of the box like ES7 and object.observe() Angular implements its own checking mechanism which can cause you a lot of headaches, especially if dealing with a lot of elements in a page. This is not an issue only specific to Angular, all front-end frameworks have this issue, until ES6 is a thing evergreen browsers support anyway.

In instances where you are plotting lots of elements into a page and wanting to interact with them, change their values (perhaps a graph for example) you are going to find Angular has a glass ceiling and when you break it, you run into performance issues that require serious refactoring (and in some cases, issues that cannot be resolved at all).

How do I use the two together?

You can roll your own custom directive functionality or you can use a robust existing solution like ngReact to implement the power of ReactJS into AngularJS.

While I have experience using both approaches, to save time, I would use ngReact and not worry about rolling your own solution unless you need additional power this library addon cannot already provide you.

An important note

Please also note that while AngularJS and ReactJS can be used together, the recommended approach is to use one or another, in an ideal world. ReactJS is not as opinionated as AngularJS and I would argue is not really a front-end framework at all. So the two cannot be compared, but one or the other or both can be used.

Inform your yourself and form your own opinions. As always, not all tools can or should be used for everything. Use what works for you and forget the rest.

Enjoy.

When Will AngularJS Version 2.0 Be Released?

Recently the AngularJS team released a slideshow showcasing what we should expect when AngularJS 2.0 is released. It detailed that controllers, directives and AngularJS as we all currently know it will be changing, with the aforementioned features being removed.

Some people are excited and others are naturally freaking out. The steep learning curve of AngularJS means that some have had to struggle and learn harder than others to get to the point they are at now and when 2.0 is released, it will be an entirely new framework.

But, wait. Do not freak out just yet. While plans and details around version 2.0 are being released already, it is far from complete or ready for primetime.

Current estimates put AngularJS 2.0 at least one year away from release, with many speculating it is about two years away from release. Considering the backbone of AngularJS 2.0’s syntax is ES6 which will not be supported in any current browser until the end of the year, it is safe to say you should not freak out.

All the proof you need is the fact version 1.3 of AngularJS was only released on October 13th, 2014 which was 12 days ago at the time of writing this post. Currently the architecture for 2.0 I believe has not even been finalised, the design could change between now and its final release.

One thing that is for certain, is you will write directives and any additional functionality for AngularJS using Google’s AtScript which is based on ES6, with some additional tweaks that make it look similar to TypeScript.

Will AngularJS survive a major version change and major rewrite? Time will tell, but the love people have for AngularJS is quite high, so things might not turn out as bad as they did for the Python 2 to Python 3 major version change.

So relax, keep on writing applications using AngularJS 1.3 and cross the bridge of 2.0 when it comes to it.