codelord.net

Code, Angular, iOS and more by Aviv Ben-Yosef

Advanced Angular 1.x: Component Communication with Require

| Comments

Angular 1.5’s components have made scope isolation the default, and rightly so. But, it does mean that inter-component communication requires more thought to get right.

Angular’s require mechanism provides a good way to allow some forms of components communication, especially across a suite of related components.

What does require let you do?
When should you use it?
Why it’s not the right tool for everything?
Keep reading!

How require works?

The require mechanism is an old one, and has been in use quite a lot for advanced Angular directive communication.

Prior to components, you’d use require in order to allow a directive access to a different directive’s controller. That allows directives to expose APIs between one another.

A directive can require the existence of another specific directive, either on its own element or on one of its parent elements.

An example of a same-element kind of communication require is used for, is adding your own validation directive to an input element, and accessing that input’s ngModelController in order to modify the validators.

Accessing parent controllers is more useful for suites of interacting components, such as the way Angular’s form validation works. Every input element in the form can notify the form that it has become valid, invalid, dirty, etc. by optionally requiring a parent ngForm controller and updating it of changes.

As you can see, require is a very powerful mechanism and an inherent part of Angular, that you can use to make your own components cleaner.

When should or shouldn’t you use require?

First and foremost, require doesn’t work in all scenarios. It can only be used by a component/directive to get access to a parent controller (or a controller on the same element). Sibling components can’t communicate using it, and neither can a parent component access its children using it (at least not directly, keep reading for an interesting option).

Another limitation of require is that it assumes the child component knows the name of the other component that it want to require. There’s no abstraction/indirection here – the name of the required component is hard-coded in the requiring component.

Also, I wouldn’t rush to use require to replace any kind of simple binding. It’s totally fine to pass some values between components using bindings–it can be more explicit and simpler to maintain. After all, it’s usually easier to understand what a component depends on if all you need to do is look at its bindings.

Require shines when it allows you setup a family of interacting components, and exposing a rich interface between them without having to wire up half a dozen bindings across multiple layers of components.

Real require example deep-dive: Angular’s forms

As already mentioned, Angular’s whole form and validations mechanism makes heavy use of require.

When you create a <form> in Angular, every element inside it that uses ng-model, such as <input>s, <select>s, etc. registers itself as a control inside that form.

You can see here in the source of ngModel how it optionally requires the form directive. In case a parent form directive exists, ngModelController uses the form directive’s controller and registers as a control. See here.

The form directive, in turn, keeps a list of all these controls and updates them on changes such as $setPristine and $setUntouched.

Notice that while there’s no direct way to access a child component from a parent component, the Angular core team did it here by using require from the child and registering it in the parent, exposing the child controllers to the parent.

Angular’s forms, in turn, have the ability to be nested inside other forms. This happens by optionally requiring a parent form controller. If require does find another parent form directive, the nested form registers in it to let the parent form know it has nested forms.

This is an excellent example of setting up a component architecture, where our components know about one another and use that knowledge to their advantage.

Real talk: How do you use require in your components

Let’s say that we’ve got this structure in our application:

1
2
3
<parent>
  <child></child>
</parent>

And we want to allow the child component to access parent component’s controller.

We’ll add a require block in child’s component definition, and then be able to access the controller inside the controller, like so:

1
2
3
4
5
6
7
8
9
10
11
app.component('child', {
  require: {
    parentCtrl: '^^parent'
  },
  controller: function() {
    var self = this;
    this.$onInit = function() {
      self.parentCtrl.someControllerFunc();
    };
  }
});

What do we have here? The require object allows us to pass as many required component as we’d like. parentCtrl is the name the required controller will be bound as in our component’s controller. ^^parent might seem live a bit of voodoo, but basically we’re saying that we require a parent component called parent to exist.

The ^^ prefix means the component has to be a parent. There’s also the ^, which means we can use a component that’s either a parent or on the current element. And if you simply provide the name, e.g. fooCtrl: 'foo' it means you expect the foo directive to exist on the current element–it will not be searched for anywhere else.

When we’re talking about components, and not directives, you almost always want ^^, though you can use just ^ if you don’t really want to make sure you’re not accidentally requiring the current element.

After we require a component, we can access it from our controller with the name we provided, e.g. this.parentCtrl. I prefer to make sure the name still uses the original component’s name, to be explicit and make maintenance easier.

If the require string is written like we saw above, it means the component is strictly required. Angular will error out if it can’t find the component we asked for. In cases where a component can operate without that required component, you can set the requirement as optional:

1
2
3
require: {
  parentCtrl: '?^^parent'
}

The question mark means that in case Angular can’t find a parent component with that name it will silently ignore it. If you’ll try to access this.parentCtrl you’ll see it’s just nulled.

With great require comes great responsibility

Require is an advanced Angular technique that can really boost certain parts of your app. It’s great for exactly those few highly-interactive components you need to write.

But, require surely shouldn’t be your default or go-to solution for all communication. Start by using regular one-way (<) and expression (&) bindings, and reach for require when it’s required (pun slightly intended).


You want to do Angular the right way.
You hate spending time working on a project, only to find it’s completely wrong a month later.
But, as you try to get things right, you end up staring at the blinking cursor in your IDE, not sure what to type.
Every line of code you write means making decisions, and it’s paralyzing.

You look at blog posts, tutorials, videos, but each is a bit different.
Now you need to reverse engineer every advice to see what version of Angular it was written for, how updated it is, and whether it fits the current way of doing things.

What if you knew the Angular Way of doing things?
Imagine knocking down your tasks and spending your brain cycles on your product’s core.
Wouldn’t it be nice to know Angular like a second language?

You can write modern, clean and future-ready Angular right now.
Sign up below and get more of these helpful posts, free!
Always up to date and I’ve already done all the research for you.

And be the first the hear about my Modern Angular 1.x book – writing future proof Angular right now.

Subscribe to get the latest about modern Angular 1.x

Spotting Outdated Angular 1.x Posts

| Comments

As Angular is maturing, it gets harder and harder for newcomers to make sense of the abundance of materials you find online. I’m pretty sure that at this point, the vast majority of Angular 1.x tutorials use outdated Angular practices–things that modern Angular 1.x projects should not be using.

In order to make it easier for everyone, I decided to grab a list of things that should indicate to you that the post you’re reading might be a bit… stale.

Using $http’s deprecated .success and .error methods

Originally, Angular’s $http service would return promises that had a couple of extra methods on them. While regular promises just have .then (and the sugar-syntax .catch and .finally), those returned from $http also had special .success and .error that weren’t standard and didn’t behave like regular promise callbacks.

I think this was done in order to make things easier for new comers to Angular that also didn’t know much about promises, but we’ve come a long way since then.

These were deprecated quite some time ago, and are completely gone in Angular 1.6.

I ranted about these more in depth here.

ng-controller and standalone controllers

Ever since the announcement that controllers are being killed in Angular 2, the community has been moving off of using standalone controllers. By “standalone” controllers I mean controllers that are used without an encompassing directive/component, e.g. using ng-controller or in a ui-router definition.

ng-controller is used quite a bit in blog posts since it makes things shorter which is helpful. The problem is that developers then go their projects and use what they saw in the examples, not knowing that ng-controller belongs to the past.

Quick aside: If you’d like to keep getting posts about the latest and greatest in Angular 1.x, subscribe to my newsletter:

Subscribe to get the latest about modern Angular 1.x

Using $scope bindings and not using controller-as syntax

Controller-as syntax was introduced in Angular 1.3 and has since become the de-facto standard for writing directives/components in Angular.

Prior to controller-as we would slap everything on the $scope, e.g. $scope.model = {name: ''} and then use the scope directly from our template:

1
<input ng-model="model.name">

This, again, makes things shorter requires less typing, but it is not the way we write proper Angular now.

With controller-as we’d initialize the controller code like so this.model = {name: ''}, and the template would be changed appropriately to not access $scope directly:

1
<input ng-model="$ctrl.mode.name">

Note that I’m using $ctrl as my controller-as name, which is the default for components in Angular 1.5. You might see vm used a lot in blog posts. That’s fine, though I’d recommend just going with the default.

Using non-isolated scopes

This is another thing that was used a lot more in the standalone controller days. Controllers by themselves never have isolated scopes, it’s up to the directive/component to isolate the controller it’s encompassing.

So whenever you used ng-controller, or didn’t specify explicitly that you want your scope to be isolated in the directive definition, you’d instead get a scope that prototypically inherits from its parent scope.

This would quickly become a non-maintainable soup of properties where refactoring is almost impossible without breaking something, somewhere.

That is why for quite some time now the rule of thumb has been to write maintainable, isolated directives.

Using directives instead of components

Since Angular 1.5 was released, introducing components, about 99% of your directives should be written using components.

Essentially, any directive that has its own template should be written as a component. So, ng-click-use a directive, anything else–components.

Yeah, most online material hasn’t been updated to use components whenever appropriate (heck, I’ve got a bunch of posts that need updating as well). But, modern Angular 1.x is components based. Do it.

I’ve written about components at length here.

Two-way binding instead of one-way binding

Another nicety introduced in 1.5 is one-way binding (not to be confused with one-time binding).

One-way binding, like components, what you almost always want to be using. It’s more explicit, more performant and more modern.

Even though it’s a rare occurrence in most blog posts, that doesn’t mean you shouldn’t be using it. It is great, and you should.

Read all about it here.

Using $watch where $onChanges would suffice

It has been common practice to stay clear of $watch when possible. And yet, going through some guides you’d think it has to be used way more often that it really does.

Ever since 1.5 introduced lifecycle hooks in components, we no longer need to use $watch to trigger some logic whenever a binding changes from a parent component.

Instead, use the $onChanges hook to perform whatever is needed without adding an extra watch, and maybe even saving you the need to inject $scope at all.

Read all about the hooks here.

———

I hope this helps you evaluate the freshness of information and understand that just because something doesn’t come up in some posts it doesn’t mean it’s not not popular – just too new to be popular in posts :)


You want to do Angular the right way.
You hate spending time working on a project, only to find it’s completely wrong a month later.
But, as you try to get things right, you end up staring at the blinking cursor in your IDE, not sure what to type.
Every line of code you write means making decisions, and it’s paralyzing.

You look at blog posts, tutorials, videos, but each is a bit different.
Now you need to reverse engineer every advice to see what version of Angular it was written for, how updated it is, and whether it fits the current way of doing things.

What if you knew the Angular Way of doing things?
Imagine knocking down your tasks and spending your brain cycles on your product’s core.
Wouldn’t it be nice to know Angular like a second language?

You can write modern, clean and future-ready Angular right now.
Sign up below and get more of these helpful posts, free!
Always up to date and I’ve already done all the research for you.

And be the first the hear about my Modern Angular 1.x book – writing future proof Angular right now.

Subscribe to get the latest about modern Angular 1.x

Avoiding ng-include for Elegance and Performance

| Comments

ng-include might seem like an innocent, helpful directive. After all, it allows us to break down a big template into simpler chunks, which makes code more readable, right?

Personally, I never liked ng-include or used it, but I didn’t care much if I saw code that made use of it. But years ago I found out that in addition to being a kind of code smell, ng-include also has a pretty significant performance hit. Since then I’ve religiously made sure my clients stay clear of it.

And yet, whenever I start working on another Angular codebase it’s always there like clockwork – another whole slew of ng-includes.

So, today, we will see why you shouldn’t be using it, for elegance and for performance!

ng-include is a code smell

I know most people use ng-include because it “makes code clearer” or “makes templates easier to maintain”. But come on, does it, really?

Look at this:

1
2
3
4
5
<div>
  <div ng-include="'header.html'"><div>
  <div>Some things go here</div>
  <div ng-include="'footer.html'"></div>
</div>

If you think that this will be easier to maintain, you’re wrong. In fact, what we just did is break a single component to have its template spread across 3 different places.

Want to make a change in the component’s controller to refactor an object? Make sure to track down all the sub-templates that use it to change it there, too.

The indirectness between the component and its newly-split template makes for a very common pitfall. I’ve seen these break and cause bugs in production so many times, because it’s the easiest thing to miss when you quickly scan a template file and do a search for the name of a variable you just changed. You simply don’t expect it to be used elsewhere.

Also, if what you’re saying is that your component’s template is so big you need to break it down, why not create a new component to make it smaller?

Most of the times, it’s not just the template that’s getting bigger, since things aren’t static. You may be making the template files shorter, but in the background we’ll have a controller that’s growing bigger and bigger, with way more responsibility than it aught to have.

My rule of thumb is that if I feel like something is getting too big, I’ll break it down to smaller components, not just try to sweep parts of the template under the rug.

But even you don’t agree, performance will kill you

I was actually very surprised when I first saw this while debugging performance issues in a big app a few years ago. And this has yet to change.

ng-include is just way slower than using a directive/component instead. Yeah, even though components create new scopes and actually introduce more watches, they are faster.

Benchmarks shows that if you have a lot of ng-includes on a screen, initial loading time of these sub-templates will be about 50%-60% longer than if you’d use plain sub-components.

And it doesn’t stop at initial loading. Once everything is one the screen, even though using a subcomponent easily doubles the amounts of watches, the impact of using ng-include on the digest cycle can be a whopping 100% increase. Yes, your average digest cycle can take twice as long, simply because of that, making everything in your app feel slower and laggy.

It’s even as simple as replacing:

1
2
3
<div ng-repeat="todo in $ctrl.todos">
  <div ng-include="'todo.html'"></div>
</div>

With:

1
2
3
<div ng-repeat="todo in $ctrl.todos">
  <todo todo="todo"></todo>
</div>

This alone, with a big enough todos list, will show you initial loading taking seconds longer, and digest cycles twice as slow. You can see it for yourself, compare this ng-include option with this sub-components option. On the upper left corner you will see ng-stats running and displaying the digest cycle time. At least on my machine this shows ng-include as 27ms components 14ms on Chrome (93% more), and 4.3ms vs 1.6ms in Safari (169% more!).

So please, stay away from ng-include. Not using it is a simple win-win – code that’s more resilient to breaking, easier to maintain, and more performant.


You want to do Angular the right way.
You hate spending time working on a project, only to find it’s completely wrong a month later.
But, as you try to get things right, you end up staring at the blinking cursor in your IDE, not sure what to type.
Every line of code you write means making decisions, and it’s paralyzing.

You look at blog posts, tutorials, videos, but each is a bit different.
Now you need to reverse engineer every advice to see what version of Angular it was written for, how updated it is, and whether it fits the current way of doing things.

What if you knew the Angular Way of doing things?
Imagine knocking down your tasks and spending your brain cycles on your product’s core.
Wouldn’t it be nice to know Angular like a second language?

You can write modern, clean and future-ready Angular right now.
Sign up below and get more of these helpful posts, free!
Always up to date and I’ve already done all the research for you.

And be the first the hear about my Modern Angular 1.x book – writing future proof Angular right now.

Learn how to make your Angular 1 app modern, step by step!

Circular Dependencies in Angular and the Injector Service

| Comments

Angular’s dependency injection is a great boon to productivity, but even it has its limits.

While not an everyday occurrence, it is quite possible to come across a circular dependency. This happens when service A injects service B, but service B in turn injects service A, usually indirectly. For example, B depends on service C which depends on A – A -> B -> C -> A forms a nice little circle.

When Angular’s bootstrap process tries to setup all the services and inject each service’s dependencies, it detects when such a scenario happens and errors out, instead of getting stuck in an infinite loop.

In most cases, circular dependencies are code smells for design that could be made clearer. Most likely you have a service that’s gotten too big, and splitting it will result in cleaner code and no circular dependency.

But, there are a few common scenarios that come up in a lot of apps where some kind of circular dependency makes sense. Let’s look at an example and a solution.

A real-world circular dependency

Enter HTTP interceptors. Interceptors are Angular’s very handy tool for handling cross-app concerns when it comes to handling HTTP requests and responses. They are probably most often used for handling authentication.

I’ve come across circular dependencies showing up in interceptors at several clients. It usually goes something like this:

As part of implementing the authentication mechanism of the app, we create an interceptor to be in charge of handling the different responses. One of the behaviors it needs depends on an external service, which in turn makes an HTTP request.

For example, we would like to redirect the user to a login page on every 401 error. An interceptor watches for these errors, and once it sees them it calls our AuthService to tell it to handle an expired session. The same AuthService depends on $http for some reason, like performing a login request.

A naive setup would look somewhat like this:

1
2
3
4
5
6
7
8
9
10
appModule.factory('AuthService', function($http) {
  return {
    login: function(user, password) {
      // This uses $http to login
    },
    handleExpiredSession: function() {
      // Redirect to login page
    }
  };
});
1
2
3
4
5
6
7
8
9
appModule.config(function($httpProvider) {
  $httpProvider.interceptors.push(function(AuthService) {
    return {
      response: function(response) {
        // Detect and handle 401 errors
      }
    };
  });
});

If you’ll try running an app with this code, Angular will spit out an error: Error: [$injector:cdep] Circular dependency found: $http <- AuthService <- $http.

That’s because $http depends on our interceptor, which depends on AuthService, which depends on $http. (Are you getting dizzy, too?)

$injector to the rescue

Just for cases like these Angular provides us with the $injector service. The injector is the programmatic way to access Angular’s dependency injection.

Using it, we can manually inject AuthService inside our interceptor and break the circular dependency:

1
2
3
4
5
6
7
8
9
10
appModule.config(function($httpProvider) {
  $httpProvider.interceptors.push(function($injector) {
    return {
      response: function(response) {
        // Detect and handle 401 errors
        $injector.get('AuthService').handleExpiredSession();
      }
    };
  });
});

Calling $injector.get('AuthService') will return the exact same singleton instance of AuthService. The main difference is that now we are performing this at a later point, after Angular has finished bootstrapping the project. At this point in time, where everything is up and running, it’s safe to inject AuthService.

Thus we have effectively broken out of the circular dependency.

Voila!


You want to do Angular the right way.
You hate spending time working on a project, only to find it’s completely wrong a month later.
But, as you try to get things right, you end up staring at the blinking cursor in your IDE, not sure what to type.
Every line of code you write means making decisions, and it’s paralyzing.

You look at blog posts, tutorials, videos, but each is a bit different.
Now you need to reverse engineer every advice to see what version of Angular it was written for, how updated it is, and whether it fits the current way of doing things.

What if you knew the Angular Way of doing things?
Imagine knocking down your tasks and spending your brain cycles on your product’s core.
Wouldn’t it be nice to know Angular like a second language?

You can write modern, clean and future-ready Angular right now.
Sign up below and get more of these helpful posts, free!
Always up to date and I’ve already done all the research for you.

And be the first the hear about my Modern Angular 1.x book – writing future proof Angular right now.

Learn how to make your Angular 1 app modern, step by step!

What Angular’s .equals and .toJson are for

| Comments

Why did Angular implement its own angular.toJson() if we already have JSON.stringify()?
Why isn’t angular.eqauls() always the same as other equality utilities, like lodash’s _.isEqual()?

I faced these questions when I first started doing Angular. Taking care to note the difference has helped me avoid some pitfalls along the way and understand Angular a little bit better.

The unique behavior of angular.equals

Once you use Angular enough you eventually notice that Angular tends to prefix its own properties and functions with $. For example, if you use ng-resource (though I think you shouldn’t) you will see methods such as $save(). Another case is scopes’ $apply, $watch, etc. and ngModelController’s $error and similar.

Because of that, the Angular team implemented .equals() so that it ignores properties that start with $. This means you can compare objects without fear of Angular’s properties getting in the way (like equality of two ng-resource instances):

1
2
angular.equals({a: 1}, {a: 1}) === true
angular.equals({a: 1}, {a: 1, $a: 2}) === true

.equals() also differs from other utilities in that it completely ignores functions:

1
angular.equals({a: 1}, {a: 1, b: function() {}}) === true

This allows us to compare objects considering only their data, not their functions or Angular-added properties.

The curious case of angular.toJson

One of the first functions any developer doing JavaScript comes across is JSON.stringify(). At first, I didn’t realize why Angular would need to add its own way of doing that.

Well, it turns out that the Angular team didn’t do it because they just happen to like rewriting everything. toJson is different in that it ignores properties starting with $$. Yes, that’s two $ signs, unlike equals().

While Angular uses the $ prefix to denote its own properties, $$ means private Angular stuff, or “don’t touch this.”

The fact toJson ignores these means you won’t get unexpected attributes on your data. The most common use case is the fact Angular adds a $$hashKey property to elements in ngRepeat (when you don’t use track by).

Say you use ng-repeat to display some list of objects you got from the server, and then after the user changes them you send them back to update the server. The silently-added $$hashKey might end up in your database, or trip up server-side validations about unexpected fields.

That’s why Angular provides toJson and uses that by default for serialization (e.g. in $http).

The companion fromJson() is plainly a wrapper around JSON.parse(), probably to provide the symmetry.

Now you know!


You want to do Angular the right way.
You hate spending time working on a project, only to find it’s completely wrong a month later.
But, as you try to get things right, you end up staring at the blinking cursor in your IDE, not sure what to type.
Every line of code you write means making decisions, and it’s paralyzing.

You look at blog posts, tutorials, videos, but each is a bit different.
Now you need to reverse engineer every advice to see what version of Angular it was written for, how updated it is, and whether it fits the current way of doing things.

What if you knew the Angular Way of doing things?
Imagine knocking down your tasks and spending your brain cycles on your product’s core.
Wouldn’t it be nice to know Angular like a second language?

You can write modern, clean and future-ready Angular right now.
Sign up below and get more of these helpful posts, free!
Always up to date and I’ve already done all the research for you.

And be the first the hear about my Modern Angular 1.x book – writing future proof Angular right now.

Learn how to make your Angular 1 app modern, step by step!

Configuring components with ui-router and ngRoute

| Comments

Angular 1.5’s .component() method is very cool, as I wrote about previously. And in general the migration path to Angular 2 recommends that we all stop using controllers in favor of components.

A lot of us are used to using controllers as the route-level objects. Each route has a controller that’s responsible for that specific route, and comes with its own template, etc.

This was comfortable since both ui-router and ngRoute allow us to easily set a controller that handles a route and inject it with dependencies using resolve.

Achieving the same with components isn’t as straightforward, but doable. Note: You might be thinking otherwise, but yes, components should be used for things that aren’t reusable, like handling a specific route. They should actually be used by default for anything that’s not a service in your app.

ngRoute

Say that we’ve got this component:

1
2
3
4
5
myMod.component('inbox', {
  templateUrl: 'inbox.component.html',
  bindings: {mails: '='},
  controller: function() {...}
});

Passing it the mails dependency using resolve is pretty simple:

1
2
3
4
5
6
myMod.config(function($routeProvider) {
  $routeProvider.when('/inbox', {
    template: '<inbox mails="$resolve.mails"></inbox>',
    resolve: {mails: function(Mails) { return Mails.fetch(); }}
  });
});

Yes, ngRoute has a handy $resolve property exposed on the scope by default, which saves us some keystrokes and boilerplate in this case.

ui-router

While the upcoming 1.0 release will handle components in a cleaner way, the above solution is available to us since version 0.3:

1
2
3
4
5
6
7
myMod.config(function($stateProvider) {
  $stateProvider.state('inbox', {
    url: '/inbox',
    template: '<inbox mails="$resolve.mails"></inbox>',
    resolve: {mails: function(Mails) {return Mails.fetch(); }}
  });
});

Yes, that’s eerily similar to the ngRoute way. Now we get rid ourselves of controllers and get onboard the component train. Choo-choo!


Do you have an existing Angular 1.x app that makes you worried about its future?
You don’t want your app to be left behind and become legacy code.
But it’s not easy clearing the time to learn Angular 2.
And who has the energy to convince management that you need to change frameworks, delay your schedules and do the Big Ol’ Rewrite?

But what if you could make sure your app keeps its options open?
What if you could make it future-proof, all the while shipping features like a boss?
You’ll work in a codebase that uses the latest and greatest, have easy maintenance and happy stakeholders!

The Future-proof Angular Guide can help you get there.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.

Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).

Learn how to upgrade your Angular 1 app easily, step by step!

$scope.$apply: What Is It Good For

| Comments

Angular has a lot of magic going on. It keeps track of all bindings and templates, and it seems like no matter what you throw at it, it will make sure that everything gets rendered and stays synced.

For a lot of us this binding magic is what initially pulled us to Angular.

But, of course, it’s not really magic, and you can come across situations where things stop working – exactly because Angular is no longer able to keep track of everything.

In those cases, the solution is almost always the $scope.$apply() function. Let’s understand why it’s needed, when should you use, and how.

The digest loop on one leg

Angular’s magic basically works by having a “heartbeat” – every time Angular sees something happened it goes over all your watchers and updates templates, syncs bounded properties, executes promises, etc.

The ability to know that something happened relies heavily on the assumption that you, the coder, won’t “step outside” of Angular’s sight.

Whenever changes happen as a result of something Angular-originated, we’re all good. So if you use ng-click to update things, or ng-model to bind a value, run code after a $timeout or talk with the server using $http, you’re all good.

Notice how all of the above are Angular-specific? That’s exactly why.

If you’ll use jQuery’s ajax() function instead of $http, you’ll see things stop working. Same goes for listening to click events natively and not using ng-click, using setTimeout, and so on.

The price we have to pay in order to enjoy the magic, is to keep using Angular’s way of doing things.

But you can’t always be inside the walled-garden of Angular

Even if you really want to, sometimes you have to do stuff another way.

The common cases are:

  • Using a non-Angular widget/plugin: Like a data visualization using D3.
    Just because it’s not using Angular doesn’t mean you don’t want to handle the events like clicks in your Angular components.
  • Binding to events natively: Angular has handy directives like ng-click, ng-focus, etc.
    But it doesn’t have a directive for every event type there is.
  • setTimeout et al: In general you should use $timeout and $interval.
    But what if you’re using code that doesn’t know about them?
    A common example is Lodash’s _.debounce() function–it uses setTimeout internally.
  • Performance: Sometimes stepping outside of Angular is necessary.

What it looks like if you don’t use $scope.$apply

Usually, if your codebase has one of the above situations and you don’t handle it properly, things will feel “lagged”.

That means that, for example, you’ll click on something and expect it to change something on the screen, but it won’t change until some time passes, or you click something else.

That’s because the changes you made actually happened in the data model, but Angular’s digest loop didn’t execute to update the templates.

Once something else triggers the digest, like a click that uses ng-click or a $http call being resolved in the background, things will render and you’ll finally see what you hoped to see in the first place.

How to return to Angular’s supervision

It’s actually pretty easy. You just need to make sure to perform your code inside a $scope.$apply() block.

For example, say that we have a native event handler for the scroll event:

1
2
3
4
5
6
element.on('scroll', function () {
  $scope.$apply(function() {
    // Now we really do stuff, for example:
    updateNavigationState();
  });
});

It’s that simple. Once you do this, Angular will execute the code in the function you pass $apply and then run a digest loop so your changes are propagated throughout the app.

There’s a slight catch here, though: You need to make sure to call $apply from outside of the Angular “zone”. If you call $apply from within it, e.g. inside a function that gets called by ng-click, you’ll get an error.

This is one of the only remaining reasons to inject $scope into your controllers in modern Angular.


Do you have an existing Angular 1.x app that makes you worried about its future?
You don’t want your app to be left behind and become legacy code.
But it’s not easy clearing the time to learn Angular 2.
And who has the energy to convince management that you need to change frameworks, delay your schedules and do the Big Ol’ Rewrite?

But what if you could make sure your app keeps its options open?
What if you could make it future-proof, all the while shipping features like a boss?
You’ll work in a codebase that uses the latest and greatest, have easy maintenance and happy stakeholders!

The Future-proof Angular Guide can help you get there.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.

Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).

Learn how to make your Angular 1 app modern, step by step!

Angular 2 Is Out: Should You Start Using It?

| Comments

“Should I learn Angular 1.x or Angular 2?”
“Can we start developing in Angular 2?”
“When should we start migrating our 1.x app to Angular 2, if ever?”
“Is anyone really using Angular 2 yet?”

In all the time I’ve been working in Angular and blogging about it, the most frequently asked question by far has been “when should I start using Angular 2?” It’s been this way since it was announced 2 years ago. Now that 2.0 has finally been released it’s becoming even more frequent.

I decided to put into writing the same answer that I’ve been giving my clients lately.

Keep in mind, this is my pragmatic recommendation for companies with teams, new hires, paying clients and business goals (i.e. businesses).

tl;dr No Angular 2 in production yet

I think the responsible approach for anyone who needs to consistently ship features in the upcoming months and support the project they’re working on for at least a year, is to wait and see how things turn out.

Yes, Angular 2 is great. Yes, I’m sure it’s going to be sooo stable and full of rainbows from now on.

But maybe, it’s gonna get changed some more in a significant way real soon. I certainly don’t feel confident enough in its stability yet to recommend any company to invest hundreds of thousands of dollars and risk missing deadlines just to be on the bleeding edge.

Why not just yet

Changes are coming

I love the core Angular team, I trust them to be professionals and I’ve been making a living writing Angular for 4 years now.

And yet, I’m not as confident as they are about the near-term stability of Angular 2. I’m pretty certain we’ll have some more medium-sized changes soon.

I mean, there were still major changes going on just 2 months ago. And now we’re really really really done changing the router? I hope so, but won’t be putting money on that.

Wait a few more months, see how things look after a few update releases.

3rd party libraries are still not baked

This is one of the most crucial points. You don’t just want Angular 2, you want an ecosystem.

Lots of libraries are still working on finalizing their Angular 2 support (and given the previous section, can you blame them for not being ready yet?).

Writing a big project now means you might be able to use the final Angular 2.0, but most other libraries will be in alpha/beta. It’s cool and edgy, but it’s not how you run a business.

If you’re not into TypeScript you’re gonna have a bad time

The Angular 2 docs for plain JavaScript, both ES5 and ES6/2016 are still MIA.

The vast majority of material you’ll find is in TypeScript. TypeScript looks very nice, and the team is pushing it very hard to be the default in Angular 2.

But can we be 100% certain that TypeScript will be the most popular way to do Angular in a year? Google has a nasty track record with languages-that-compile-to-JS (cough GWT cough Dart cough). Are we sure this is the one that’s going to take off?

And since TypeScript is used mainly in the Angular corner of the universe, it means investing in learning a language, tool chain, editors, and more – quite a leap of faith.

If you want to do it in JS, which is officially supported, you’re gonna have a very hard time finding resources right now.

Heck, there’s even Dart(?!?) documentation on the official site before the JS docs. I mean, come on.

Lack of docs and knowledge in general

In my side projects I might enjoy investing lots of time digging into a problem in order to understand how best to use a tool for a specific need.

At work, where my real intention is to deliver working products, I rather focus on my business’s problems and actually find answers for questions on Stack Overflow etc. Yes, things are getting better, but they’re not quite there yet.

Not just for Angular 2 itself, but also for all the libraries which haven’t reached a stable release yet or aren’t widely used (i.e. all of them).

Hiring experienced developers in the near term

I’ll be the first to say that any developer worth their salary should be able to learn whatever tool is thrown at her. And yet, no one can become a master in something this complicated in a couple of days.

If you have business goals you need to accomplish and expect to hire more developers soon, it will be about an order of magnitude easier to get someone experienced in Angular 1.x than 2.

Who should use Angular 2 in production?

Anyone that doesn’t care about the above.

That’s basically people working on small scale projects, POCs and prototypes.

Then when should we start using Angular 2?

I used to think 2.1 would be a good time, but with the announcement of semantic versioning coming to Angular, it sounds like Angular 3 will be good time (expected to be released in Q1 2017).

In the mean time

LEARN

Just because you shouldn’t writing major projects in it at work doesn’t mean you can’t start prepping for it.

Start learning, do some tutorials, play with TypeScript, write a few sample apps (yes, you’re probably going to write another To Do app).

It’s good to be in the loop, and even if things change – you don’t care about maintaining your sandbox code, you just care about starting to be acquainted with the concepts.

Don’t get stressed about the hype

The JS community is mainly obsessed with hype, and in our Angular part of the world, that means Angular 2 stuff.

You can’t open reddit/ng-newsletter/whatever without seeing Angular 2 posts. Actually, on most of them the majority is Angular 2 posts.

This might make you feel like you’re the only one keeping the lights on for Angular 1. You’re not. Really.

I promise.

Heck, I wrote quite a few Angular 2 posts. That doesn’t mean you should start using in in production just yet.

Prepare your existing Angular codebase

Maybe in 6 months we’ll all as a community come to the realization that it’s best to rewrite all your existing code in TypeScript and Angular 2.

Maybe we’ll just settle on interoperability between Angular 1.x and Angular 2.

And maybe we’ll see Angular 2 needs some more time and keep at it with plain 1.x

(And yes, maybe you’ll decide that it’s best for you to drop Angular entirely. Ssssh.)

But, in just about 99% of the cases you’ll profit from making sure the current Angular 1.x development you do is modern Angular 1.5.

Writing component-based Angular, getting rid of controllers, etc. will benefit most code bases and make pretty much any future move easier.

I wrote about some aspects here.

I also plan on releasing a course about modern Angular 1.5 soon: the Future-proof Angular Guide.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.

Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).

Learn how to make your Angular 1 app modern, step by step!

Animating Transitions in 2 Minutes with ngAnimate and CSS

| Comments

In my previous post, which is a short introduction to ngAnimate, we saw how just including ngAnimate in a project and a dozen lines of CSS can add slick animations to ng-repeat easily.

That was a very simple use-case, and in this post I want to show you how you can use it to animate transitions inside any container you have, with about the same complexity!

Our example, simple pagination

Say we have a regular component that displays a list. It has basic pagination – we only display a fragment of the list and there’s a “next” button to move on to the next fragment.

Our animation-less component would look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
angular.module('app', ['ngAnimate']).component('parent', {
  template: [
    '<button ng-click="$ctrl.nextPage()">Next</button>',
    '<div class="container">',
      '<div class="page">',
        '<div ng-repeat="line in $ctrl.pages[$ctrl.currentPage]" 
              ng-bind="line.text"></div>',
      '</div>',
    '</div>'
  ].join(''),
  controller: function() {
    var self = this;

    this.currentPage = 0;
    this.pages = [
      // Here be pages of stuff...
    ];

    this.nextPage = function() {
      self.currentPage = (self.currentPage + 1) % self.pages.length;
    };
  }
});

Now if you’re following along you can see that this is basically Angular 101. A simple component with a list of pages, and our template just displays that list with a little button to advance pages. Nothing fancy.

At this point we are sans-animation. Pressing the “next” button would instantly swap the contents of the page.

Not the best UX in the world, right?

Introducing ng-animate-swap

ng-animate-swap is a nifty little directive that’s part of ngAnimate (full docs here). What it does is… well… animate when you swap things!

Where in the previous post we saw how ngAnimate adds events to a set of situations it knows (e.g. leave, enter and move for ng-repeat), ng-animate-swap allows us to add leave and enter events to any DOM element!

You do it by passing ng-animate-swap an expression to watch for. Whenever that expression changes, it will trigger the animation to swap the container from the previous state to the new one.

In our case, we would like to swap the element with the page class, so it will animate whenever you move between pages.

The line we change in the template, after the changes, looks like this:

1
<div class="page" ng-animate-swap="$ctrl.currentPage">

Pretty simple, right? We tell ng-animate-swap to listen for page changes.

Now, with a dozen or so lines of CSS we’ll add a basic animation and, voila, here’s your slick animation:

I won’t go into the CSS in this post, but you can see if for yourself, along with a live example, here.

With basically no JavaScript changes and very minimal template changes, ngAnimate gives us a lot of power to add animations to our apps.

Keep that in mind the next time you need to spice a screen up a little.


Do you have an existing Angular 1.x app that makes you worried about its future?
You don’t want your app to be left behind and become legacy code.
But it’s not easy clearing the time to learn Angular 2.
And who has the energy to convince management that you need to change frameworks, delay your schedules and do the Big Ol’ Rewrite?

But what if you could make sure your app keeps its options open?
What if you could make it future-proof, all the while shipping features like a boss?
You’ll work in a codebase that uses the latest and greatest, have easy maintenance and happy stakeholders!

The Future-proof Angular Guide can help you get there.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.

Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).

Learn how to upgrade your Angular 1 app easily, step by step!

ngAnimate Basics: Pure CSS ng-repeat Animations

| Comments

Little touches of animation can make any app feel so much more slick, mature and responsive. Adding animations, though, can be a PITA that involves making your tidy code messier. Add this class, stop that animation, find the right DOM element. Bleh.

Angular’s own ngAnimate can really save you a lot of work and keep your code clean. But its documentation can be a bit hard to grok.

In this post you’ll see how in just a few lines of CSS you can add nice animations to your ng-repeats, using ngAnimate.

Setup

First, make sure that your app has ngAnimate, since it doesn’t come built-in with the vanilla angular.js file. That means that you should probably add angular-animate to your dependencies manager, and make sure to add 'ngAnimate' to your module’s list of dependencies (e.g. angular.module('app', ['ngAnimate']).

ngAnimate basics

The way ngAnimate works is that it has support for several scenarios which you can then add animations for.

In our examples, we’ll use its support for 2 ng-repeat events: enter and leave. The enter event is triggered when a new element is being added to collection you are ng-repeating. The leave event, surprisingly, triggers when an element has been removed. (There are many more cases, like an element whose position changes in the collection, and support for ng-show, etc.)

To use these events with basic CSS animations, you need to handle 2 situations: once the event is starting to happen, and once the event has completed.

For example, let’s think about our enter event. We will make it so that every element that gets added to our list will not just “pop” on screen, but instead will slowly appear by animating its height from 0 to the wanted size (kind of like jQuery’s slide animations).

So, at the triggering of the enter event we will add the CSS property height: 0, and at the end of the event (called “active” in ngAnimate) we will set the height to its regular size.

Show me the code

Well, there’s actually not any real code, but some HTML and CSS. Yeah, it’s that simple :)

Say our list gets rendered like so:

1
2
3
<div class="slide" ng-repeat="item in $ctrl.list"
     ng-bind="item.name">
</div>

Notice that every element in the ng-repeat has the slide class. Lets animate it:

1
2
3
4
5
6
7
8
9
10
11
12
13
.slide {
  overflow: hidden;
  transition: 0.3s;
  height: 30px;
}

.slide.ng-enter {
  height: 0;
}

.slide.ng-enter.ng-enter-active {
  height: 30px;
}

As you can see, we set the regular CSS, and then handle the 2 states of the ngAnimate enter event: once it triggers the height is 0, and it slowly grows back to 30px. The actual animation is done by the browser automatically, because we’ve set the transition CSS property.

It looks like this:

That’s it, pretty simple right? I’ll be writing soon about more advanced ngAnimate techniques.

You can play with an online example here, which also shows the use of the leave event.


Do you have an existing Angular 1.x app that makes you worried about its future?
You don’t want your app to be left behind and become legacy code.
But it’s not easy clearing the time to learn Angular 2.
And who has the energy to convince management that you need to change frameworks, delay your schedules and do the Big Ol’ Rewrite?

But what if you could make sure your app keeps its options open?
What if you could make it future-proof, all the while shipping features like a boss?
You’ll work in a codebase that uses the latest and greatest, have easy maintenance and happy stakeholders!

The Future-proof Angular Guide can help you get there.
With this no-fluff course you’ll learn how to quickly adapt your existing Angular 1.x app to the latest components paradigm, as you go about your regular work.
You’ll gradually turn your app into something that is modern and idiomatic, converting directives and getting rid of controllers.
And then, once your app is shaped The Right Way™, you’ll be able to keep shipping like a boss, and have your options open.

Sign up to be notified when the course is ready (and get more of these pragmatic Angular posts in the meantime).

Learn how to upgrade your Angular 1 app easily, step by step!