codelord.net

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

Not Everything in Angular Should Be a Singleton

| Comments

When all you have is a hammer, everything looks like a nail.

Angular services/factories are singletons. This has caused so many teams to forget about the joy of self contained objects that take care of themselves.

You don’t have to put all your code in static singletons and sling dummy json objects back and forth across your app.

You can enjoy real objects that make code easier to maintain!

How your code probably looks

You have a service for handling some kind of model, e.g. a Course would have a CoursesService. That service would be responsible for creating the courses and manipulating their data.

For example, you’ll use CoursesService.create(name, students, schedule). That will return some json object that you’ll then keep in your controller.

Whenever the controller would need some data about the course, it would have to use the service, passing it the object:

CoursesService.getEndDate(course)

Not only is this not very OOP-ish, it means that every binding you have in your template, e.g. to show the end date, would have $ctrl.getEndDate(course) which you’ll then implement in the controller just to proxy it to the CoursesService.

Also, having the course json object by itself isn’t usually enough, and to use it you’ll have to inject CoursesService.

Bleh.

How your code could look

Instead, we can create a real Course model that encapsulates its own data and knows how to manage by itself.

We create a service like so:

1
2
3
4
5
6
7
8
9
10
angular.module('app').factory('Course', function() {
  return Course;

  function Course(name, students, schedule) {
    this.name = name; // Etc.

    // Put the logic here!
    this.getEndDate = ...;
  }
});

And now, all of a sudden, our code has become nicer!

You create a course using new Course(...) and then just use this instance, instead of always holding on to an object and the service.

And, for example, your templates could now directly use $ctrl.course.getEndDate() instead of proxying it using the controller.

Huzzah!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

$scope.$watch and controllerAs

| Comments

You know that by now your Angular code should be pretty $scope free. The controllerAs syntax makes it so you shouldn’t be accessing $scope in order to store information on it.

But, scopes are still an important part of Angular and sometimes you have to use them.

One not-so-rare example is the $scope.$watch() function. With the introduction of controllerAs syntax we now have 2 seemingly interchangeable ways to use it. But, they are not exactly the same and I think you should only be using one. Let’s quickly go over it.

The olden days

In the pre-controllerAs days we would put everything directly on the $scope.

So, you might have $scope.foo and then, to watch for changes, you’d use $scope.$watch('foo', fooChanged).

That just worked. But with controllerAs it’s not that simple. If in your controller code you use this.foo, you can no longer just watch for changes using $scope.$watch('foo', ...).

That’s because the 'foo' part looking for foo directly on the scope, not your controller’s instance.

The bad option – using the controller’s name

The way a lot of people are solving this is by using the controller’s name in the expression.

If you’re using Angular 1.5’s components then the controllerAs name is $ctrl by default. So you’d use $scope.$watch('$ctrl.foo', ...).

If you have a different name, like stuffCtrl then you’d use $scope.$watch('stuffCtrl.foo', ...) etc.

I don’t like this for several reasons:

  • It feels foreign to me to use a name that’s essentially only used in the template (the controllerAs name), while the rest of the controller code uses this or vm.
  • Using this name means that in case you decide to rename it, you’ll have to look for it in both the template and the controller code.

The right way

It was always possible to pass a function to $watch() as the expression that you’re keeping track of.

Because of that, it’s possible to do something like this:

$scope.$watch(function() { return vm.foo; }, ...)

(Of course, it’s even nicer if you’re using ES6’s arrow functions.)

I believe this is better, even though it involves more typing, because it keeps your controller code consistent. You always refer to things the same, and there are no magic strings.

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Understanding Angular’s One-Way Binding

| Comments

Angular 1.5 introduced a new kind of binding option to directives/components. Along the often-used = for regular two-way binding and & for expression binding, we now have <: one-way binding.

What does it mean exactly?
When should you use it?
When shouldn’t you?
And why did we even need another kind of binding?
Sit tight!

How today’s two-way binding works

Today’s two-way binding basically has 3 aspects: passing the reference first, synchronizing changes from the parent and synchronizing changes from the child:

Passing the same reference means that when your child component is initialized with foo="$ctrl.foo" then Angular will pass it a reference to the same foo object as in the parent controller. This initializes them to start working off of the same data.

Because this is the same reference, changes made to a property on foo by either parent or child will be seen by the other, e.g. $ctrl.foo.baz = 'a'.

Synchronizing changes from the parent means that if our parent component overrides foo with a new object, i.e. this.foo = otherFoo then Angular’s watch will notice and change the child component’s foo to reference the same new object.

Synchronizing changes from the child are the other coin of the two way binding – if the child assigns a new reference it will also be copied to the parent.

You ain’t gonna need it

Even if you knew about the synchronization from the child to the parent, and most don’t know, it’s likely you never actually had to use it.

Having the objects be initialized with the same reference is enough for 95% of the components. The synchronization from the parent likely covers another 4.9%.

The other way around is just obscure, costs you in performance and, to be honest, sounds like a code smell.

Be explicit and don’t pay for what you don’t need

Basically, your rule-of-thumb should be to always default to one-way binding, like so:

1
2
3
4
5
6
7
angular.module('app').component('myComponent', {
  templateUrl: '...',
  bindings: {
    foo: '<' // <-- This!
  },
  controller: function() { ... }
});

It is always better to be explicit in code. One-way binding means you’re not doing anything funky to the object reference.

Also, there’s a performance penalty to using two-way bindings when you don’t need them. One-way bindings require less work on every digest and so you can also gain a small boost (I say small because from measuring it seems small – but it’s essentially free, why not?).

Cheers!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Understanding Angular’s & Binding

| Comments

Angular has several cases where the syntax trips you up, or where it’s just not clear what should you use. Most famously, there’s services vs. factories and ng-show vs ng-if. More recently we now have components vs. directives.

Another thing that I’ve seen people get mad about time after time is the & binding for passing functions to directives/components. “The & callback binding trips me up EVERY TIME I just hate it.”

Let’s understand exactly what it is. Once you grok it, you’ll never get it wrong again.

Can you use it in a sentence?

First, here’s an example component that has one of these & bindings:

1
2
3
4
5
6
7
8
9
10
angular.module('app').component('foo', {
  templateUrl: '...',
  bindings: {
    callback: '&'
  },
  controller: function() {
    // ...
    this.callback();
  }
});

As you can see, we have a simple binding called callback. The usage of this component would look something like this:

<foo callback="$ctrl.myCallback()"></foo>

This means that whenever the foo directive would call the callback binding, the myCallback function on the caller’s controller would be triggered.

The tricky bit: parameters

Now, what everyone get mixed up with is using & with functions that get parameters.

Say that our callback wants to pass an argument. The component would be created like so:

<foo callback="$ctrl.myCallback(value)"</foo>

But inside the component, we calling syntax would look quite foreign the first time you see it:

this.callback({value: 'whatever'});

WAT

Yes. Doing something like this.callback('whatever') wouldn’t work.

What’s going on?

Technically speaking, when you use the & binding, Angular doesn’t just do 2-way binding the regular way.

It takes the expression you use, in our example $ctrl.myCallback(value) and saves it.

When you call it, Angular evaluates that expression on the parent scope.

You see, when using & you don’t have to pass function, though that’s what we do 99.9% of the time. You can pass in any expression, and it would work.

So, in our example, we could have used:

<foo callback="$ctrl.values.push(value)"></foo>

And whenever we’d perform this.callback({value: 'whatever'}) it would get appended to the parent controller’s values array.

Because the & binding is so generic, it doesn’t really have a notion of function parameters – the expression could be anything.

When you pass it the object, it is actually a mapping of local variables to override. Angular takes the expression and evaluates it in the parent scope, but with the values you pass it added as the locals.

Wiseass note: Yes, this means we can call this.callback({value: 'whatever', $ctrl: something}) and the function call would be performed on the something object and not on our parent controller – because we override it!

Dear god, why?!

This was done so that you’ll be able to pass expressions instead of functions to anything in Angular.

Have you ever used ng-click="$ctrl.value = true" or something along those lines? Sometimes it’s easier to not use a function.

The core team wanted us to have this flexibility, and the price is that we have to call function in a way that feels a bit clunky.

But remember: You’re not really calling a function, you’re evaluating the expression with those values!

Now you know

If you’ll make the mental switch from treating & as “function binding” to just “expression binding”, I think you’ll be alright from now on.

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Using ES6 Arrow Functions in Angular 1.x + Cheatsheet

| Comments

ES6 is becoming more and more popular among the JS crowd. I’m guessing that the first feature anyone that moves to ES6 starts using is arrow functions. And the recently released Angular 1.5 introduced support for injecting dependencies into arrow functions. Unfortunately this support added a couple of nice pitfalls for newcomers that are important to understand and avoid.

Quick background on arrow functions

In case you’re not familiar with these, they basically look like this:

1
2
3
(arg1, arg2) => {
  return arg1 + arg2;
}

Which, unsurprisingly, maps to:

1
2
3
function(arg1, arg2) {
  return arg1 + arg2;
}

Note: There’s a lot more syntax sugar that makes these awesome, like array.map(x => x.name). They can really save up on some typing and make code cleraer. Get the cheat sheet at the bottom of this post for the full list!

An important feature of arrow functions is that they bind the this value.

Most JS developers are well versed in the practice of keeping a reference to your “real” this value, e.g. var self = this or var vm = this. This is because every function you then declare inside the object might have a different this value assigned to it at runtime, which makes for very fun bugs.

Arrow functions do this for you behind the scenes, so that inside an arrow function you can freely use this and it’ll be the same this as in its parent scope.

The pitfalls

I like arrow functions very much. First, because they mean I need to type less, which is always a good thing. But mainly because using arrow functions means I don’t need to declare a self var anymore or think about what this means as often.

The main problem is when people assume they can just start using arrow functions everywhere, and say goodbye to the regular syntax. But that’s not the case.

Arrow functions should never be used for constructor functions.

They are always anonymous and have no prototype, which means they are not newable. And of course using them as constructors is wrong since a constructor should not be using its parent scope’s this value.

The Angular-Arrow function rule of thumb

The most common constructor functions in Angular are controllers and services.

So, to be safe, never use arrow functions in module.service('Service', ...) calls and not when passing a controller function as controller: ... when defining components/directives/etc. (and also not in module.controller() calls, but you should hopefully not have any more of these).

Personally, I don’t like it when all my files don’t look the same, and I prefer my style guide to reduce thinking.

Because of that I simply recommend to not use arrow functions as the function parameter to any module.something() call (where something can be service, factory, directive, run, etc.) and never when passing a controller function.

Happy arrowing!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Directives are not what they were a year ago

| Comments

Since the very early days of Angular, directives have been one of the gnarliest pieces to grok and wrap your head around.

There have been countless of posts on forums and groups asking what exactly are directives and what should they be used for? And thousands of words were published trying to answer these questions.

But, most of those no longer hold true. If you’re just getting into Angular 1.x, most of what you’ll find online about the role of directives is outdated.

And if, on the other hand, you’ve been doing Angular for quite some time now, then you should know that things have changed. The community is flowing in a different direction, and you should get with it (or at least know what you’re missing out on).

The “old” thinking behind directives

In the first version of Angular, controllers were held as a very big part of the framework where most of the logic would lie.

Directives, it was commonly said, should be used only for DOM manipulation or for reusable components.

When learning Angular, you’d be told that you can wait with learning about directives, since you rarely write ones yourself. After all, with the awesomeness of Angular you don’t need to reach your hands down to the DOM on a daily basis.

And, really, how many reusable components do you write in a given week?

The new standard – directives and components for ALL THE THINGS

Over the past year, Angular 2 has matured and the migration path to it is getting clearer. With that, the Angular team have been moving Angular 1.x towards these new concepts.

We know that controllers are gone in Angular 2, and you should be killing yours.

The old/new stars are directives, mostly in their fancy new cloths as components.

I’ve written before about what components are and how you should use them. 90% of the time you should be able to use a component instead of writing a directive.

And you should basically no longer be writing any controllers that are not directive-controllers or component-controllers.

Yes, even if that directive is not reusable at all and will only be used in a single place. And even though there’s no DOM manipulation going one.

The world is changed. Do not shy away from directives. Nowadays, Angular consists of UI code in directives/components and logic in services. That’s it.

What to use directives/components for

  • Pages
  • Reusable components
  • DOM manipulation
  • Wrapping up non-Angular widgets
  • Non-reusable components (e.g. just breaking up a bigger component to smaller pieces)
  • Routes

Basically, the rule of thumb is: don’t use controllers, put logic in services, everything else is in components.

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Angular Performance: Updating bind-once elements

| Comments

Performance can be tricky with Angular. It’s quite easy to have a page that’s slow or unresponsive because you got too many watchers going on.

Angular 1.3 shipped with the new bind-once syntax, but I hardly see people use it. Even if you add it, you hardly never want things to never change again.

Usually, you have a bunch of stuff that change together. Plainly using bind-once would remove all the watches and make your page responsive and your digest cycles fast. But, how would you go about updating it?

It’s a bit tricky, but doable. In this post we’ll show an example of performing such an optimization.

Our use case: search results

Let’s say you have a page in your app that let’s you search something. You get from the server a response with 100 items that you them display:

1
2
3
<div ng-repeat="item in $ctrl.results">
  <div>{{ item.name }} - {{ item.description }}</div>
</div>

If we display 100 results at once we already have 200 watches: 2 bindings (name and description) per item displayed.

This can easily get out of hand.

But look at your results. They’re not going to change individually. The will only change as a whole, when, for example, the user goes to the next page or types a different search query.

Let’s get rid of them watches!

Binding once

You might first start with something trivial like this:

1
2
3
<div ng-repeat="item in $ctrl.results">
  <div>{{ ::item.name }} - {{ ::item.description }}</div>
</div>

This simple change (adding :: in two places) rids us of those 200 watches. Yay!

But, what would happen if you now update the description of items inside $ctrl.results, e.g. because the user marked them as read?

Nothing.

It’s a bit crappy that there’s no easy way to tell Angular to refresh these bind-once expressions.

But don’t give up yet.

Note: In this example, if you add/remove elements from $ctrl.results they will be added/removed to the ng-repeat. If you never change the inline elements you wouldn’t need anything more than this. This is a simple example, but pages with performance problems usually aren’t simple :)

Forcing an update of bound-once content

This requires a bit of coding. Basically, we want to tell Angular to throw away those frozen elements and recompile stuff to use our new content.

Our end result would look like this:

1
2
3
4
5
<refresher condition="$ctrl.lastUpdate">
  <div ng-repeat="item in $ctrl.results">
    <div>{{ ::item.name }} - {{ ::item.description }}</div>
  </div>
</refresher>

We wrap our content with a specially crafted directive, refresher. This directive listens for a given property. Once that property changes its value, refresher recompiles the content inside it.

This means that we effectively have a single watch active, and once that watch’s value changes everything updates.

In our case, we can have lastUpdate be whatever you want as long as it is updated when your content changes. I usually just use a timestamp that I update whenever the content changes.

Here’s how refresher looks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.directive('refresher', function() {
  return {
    transclude: true,
    controller: function($scope, $transclude,
                         $attrs, $element) {
      var childScope;

      $scope.$watch($attrs.condition, function(value) {
        $element.empty();
        if (childScope) {
          childScope.$destroy();
          childScope = null;
        }

        $transclude(function(clone, newScope) {
          childScope = newScope;
          $element.append(clone);
        });
      });
    }
  };
});

There’s not a lot of code going on around here.

refresher is a basic directive (why not a component? because components have to have isolated scopes, which I don’t want in this case).

This directive basically watches for changes in the value of whatever you pass to its condition attribute.

Whenever that value changes, refresher throws out whatever it previously contained and recompiles things, so they’ll appear on screen updated.

This is a basic example of using the $transclude service manually.

That’s it!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Angular 1.5 new component lifecycle hooks

| Comments

It’s only been 2.5 months since Angular 1.5 came out, introducing components. Most companies haven’t even had the chance to upgrade yet. Yet, in the mean time, the Angular team released 3 more releases.

With 1.5.3 components have become a bit smarter and a bit more compatible with Angular 2. This new version introduced some new and useful lifecycle hooks to directive/component controllers. Let’s take a deeper look at how these can help you write cleaner code!

Recap: $onInit

I’ve previously written on $onInit, the first lifecycle hook introduced with version 1.5.

It provides you with a nice and clean place to initialize your component after all of its bindings have been set.

This roughly maps to Angular 2’s ngOnInit.

New: $onChanges

This new hook is similar to ng2’s ngOnChanges. It is called whenever one way bindings are updated, with a hash containing the changes objects.

Prior to this hook you sometimes had to use a $watch in order to do some work whenever a value you’re bound to changes. Using this hook makes things clearer and removes the need to introduce a watch and a dependency on $scope.

New: $onDestroy

A hook that gets called whenever the controller’s scope is being destroyed.

Whenever you used external resources, or add DOM listeners, in your component you’d (hopefully) use $scope.$on('$destroy', ...) in order to clean up when your component would get destroyed.

This hook, similarly to $onChanges, makes things simpler and saves us a dependency on $scope.

Unsurprisingly, this is equivalent to ng2’s ngOnDestroy.

New: $postLink

This isn’t something that comes up often, but maybe you got bitten in the past by the difference between a directive’s link function and the directive controller’s function.

These two do not run at the same time: the former runs after the DOM is ready while the latter isn’t.

This means that for some DOM manipulation and operations you had to work harder in order to perform it in a component (or maybe you had to use a directive).

Now we can use $postLink and know that all of our child components are ready. This, together with the $element injectable we have in components makes it even less likely that you’ll need to write an old-style directive. w00t!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Please leave the ng prefix alone

| Comments

This might be obvious to the Angular veterans here, but I keep coming across this. Every time that I go through a new Angular codebase I find at least one directive or service that uses the ng prefix in its name.

And really, we can’t blame people for doing this since when you’re just starting with Angular use keep seeing ng-this and ng-that. How is a newcomer supposed to know any better?

But please, stop. And if you have any of these remaining in your codebase, take an hour and rename it, for the love of all that is holy.

The ng prefix is reserved for Angular’s own stuff

Yes, it’s theirs. And we’re lucky they use a prefix, because it makes it easier to spot what is part of the standard library and what isn’t.

At least, it’s easy as long as you don’t shove your own stuff there.

There also so many default directives that there’s no chance you know all of them and it’s very easy to clash with some existing stuff. So please don’t.

There are open source libraries that still misuse the prefix, but the numbers are dwindling.

A very prominent example is ng-grid which has been renamed to ui-grid.

You don’t even have to use a prefix

I’ve seen lots of projects (not libraries) that do just fine without prefixes. But even if you decide to use one, just pick a different one. Here, you can use fj. It’s easy to type. Have a blast!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Naming Your Controller-As Consistently

| Comments

Conventions have always been a problematic part of Angular, especially when they seem to change all the time.

A very common issue that I’ve been asked about again and again is what name to use in controller-as.

Here are my 2 cents on a style that, to me, makes the most sense.

First, understand that the options basically divide to either using the same name in all your components/directives, or to use a specific name in each.

I strongly recommend to use the same name in all templates. It means less typing, less thinking about boring details and of course means easier refactoring down the road.

Now, the question is what name should you use. Prior to Angular 1.5, the community seems to have settled on “vm” as the name (e.g. that’s the default in John Papa’s style guide).

But, with the introduction of components in 1.5 the default there is now “$ctrl”. Even though I personally dislike the look of $ctrl I have to recommend sticking to it. It is only a matter of time before this becomes the de-facto standard as the community upgrades to 1.5.

What about referencing parent controllers??

One of the arguments I’ve heard quite a bit for using a different name in each directive/component is so it will be possible to reference parent controllers in the scope.

But, you should never do that. Your scopes should virtually always be isolated, so that name clashing would be impossible.

And in the (truly) rare occasion where you do reference some parent controller you should do it using the require mechanism.

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!