Wednesday, November 19, 2014

ngEurope: Angular 2.0 Core

To really learn about the changes in Angular 2.0 Core, I recommend you watch the video of the presentation:

Here are some things I noted:

There is still HTML templating, but some ng- attributes have gone away. The following examples were given:

<button (click)="doSomething()">Go</button>
<input [value]="user.name">


I'm not sure what the difference is between the () and the [] though.

Angular 2 will bind to properties of elements, not attributes. For example, a checkbox doesn't have a checked attribute. It does, however, have a checked property. Some properties are serializable into attributes, but not all. So it gives Angular more options if it binds to properties.

Angular 2.0 will drop a lot of things we're familiar with: controllers, directive definition objects, $scope, angular.module,...

The goals is to replace controllers with a component model (code that could be used in a non-Angular app too). Directives will be replaced with annotations, and $scope is no longer necessary now that the component is the execution context.

Angular 2.0 will no longer use jqLite. Instead, it will use the raw DOM, as this way of working has become much better since the haydays of Angular. The mentioning of this (dropping jqLite) produced quite some applause. Moving on.

A last thing worth mentioning is that instrumentation will be built into the framework. This will make it easier to analyze performance, see what's happening,...

There isn't really a lot of info on the details of all this, and there is some criticism on this approach. The future will tell if the decisions taken are the right decisions, and how easy Angular 1.x code will be portable to 2.0 code. But I suspect there will be possibility for community feedback in due time.

Wednesday, November 12, 2014

ngEurope: AtScript

The second day of ngEurope started with... the keynote. A bit strange, but whatever. Misko Hevery gave a good explanation of the future of javascript, and how it's coming to us early with AtScript.

First, he stressed they were not building a new language. But the fact is that the current state of javascript makes it hard to develop complex applications and frameworks (hence the invention of TypeScript). Misko gave the specific example of a complex directive (check out this slide, with two ways of injecting dependencies), but large codebases in javascript are hard in general.
   
Building a new language might be tempting, but you could make a whole new set of mistakes, people would have to learn something new,... The XKCD comic on standards was in one of the slides:


Types are contracts between developers, ways of communicating intent and capabilities. Especially on large projects and large teams. Ideally, we would have optional types. Optional, because the existing code should keep working, and in javascript, there are no types.

Misko also mentioned annotations and introspection.

Annotations can communicate intentions by specifying the type of a field or parameter.

These annotations are available at runtime and this is where introspection comes into play.

And that is what AtScript is: optional types, annotations and introspection.

It is a run-time type system. This means that types are checked at runtime. Your code is compiled to assertions (for example, asserting that a parameter is of a certain type). AtScript can handle
  • nominal assertions (i.e. it's an array)
  • structural assertions (i.e. a given string matches a certain regex)
  • generics

An example Misko mentioned, is that this means it's possible to check the server JSON response for the correct type.

He ended with an overview of the past, present and future of javascript. These two slides should clarify it better than I can type in words. The nice thing is that AtScript code is valid TypeScript code. This means the step to solid IDE support should be smaller too. They are already talking to IDE vendors.

The next steps are static type checking, alignment with TypeScript, an ECMAScript proposal, browser support and finally an ECMA standard.

I don't expect to use this in the near future, but it is nice to know what's coming.

Check out all the slides here.

Monday, November 10, 2014

ngEurope: Angular from scratch

One of the most impressive sessions at ngEurope was Matthieu Lux programming Angular from scratch. He literally started with an empty html file and coded in the javascript for databinding. His full demo can be seen on YouTube and is very much worth looking at. It will help you understand the 'magic' behind Angular (even though Angular is more than just databinding). You can also look at the source on GitHub.

Simply said, Angular keeps a list of watchers that watch elements and check for changes. Changes are as simple as

newValue !== oldValue


The newValue is retrieved via a watcher function (watcherFn). The oldValue is stored for later reference. If the value changes, it calls the listener function (listenerFn), which does something based on the new value. So a watcher is basically just an object with a watcherFn and a listenerFn.

There is a continuous loop that runs and loops over all watchers. This is the $digest loop. You can call the digest loop yourself, but it is safer to call the $apply function. The $apply function gives you a try-finally block that will call the $digest function in the finally block. This way, if there is an exception in any of your watch expressions, the digest will still run for others.

How does Angular know what to watch? That's where the compiler kicks in. The compiler loops over all elements and checks if one of the registered directives is present (like ng-bind). If so, it calls this directive. The directive will use a watcher to know what to watch, and to know what to do when the value of what it is watching has changed.

A watch can look like this:

return $scope[$attributes['ng-model'].value]


For an element with a directive like ng-model="name", this will end up calling:

return $scope['name'];


My short post does not do this session any justice, so I cannot recommend the video and code enough. It is very eye-opening to see this unfold in about 30 minutes.

Friday, November 7, 2014

ngEurope: Angular's new router

Rob Eisenberg was at ngEurope to talk about Angular's new router. Rob is the author of Durandal and has recently been added to the Angular team. Together, they took a good look at the different routers out there (SammyJS, EmberJS, Durandal,...). They used what worked and improved what didn't to create a new router for Angular 2.0. What's cool is that they backported it to Angular 1.3. So you can already start using it.

Basic features are what you would expect from a router:
  • configuration
  • 404 handling
  • history manipulation
Also basic for some, but new for Angular:
  • Conventions
  • A navigation model (You will recognize this if you've played with Durandal before. The new router can build a special model that you can use with ng-repeat to generate your navigation.)
  • Document title updates
But there's more.

Dynamic loading
Load controllers on the fly. Again, if you have experience with Durandal, you'll know this is interesting when your application starts to grow. Instead of bundling everything in one download, scripts can now be requested when needed.

Child Apps
This is a very cool new feature that will allow large teams to split up their app, library developers to provide a router for their library, etc. What this feature does is it provides the possibility of having a specific router for a specific controller. Say you want to create a library for user management, complete with views, routing, controllers,... You can then easily plug this into your 'parent' app, that of course already has a router.
This also means you could take an entire app and drop it into another app. There are multiple possibilities with this, but one that instantly came to my mind is one big Intranet 'app' that actually consists of multiple sub-apps, all developed by separate teams.

Screen activation
It is now possible, with canActivate and canDeactivate, to stop navigation, even if another router is handling the navigation. This can be useful in several cases, for example if the user has unsaved data.
The canDeactivate function is called when we're navigating from a controller. The canActivate is its counterpart, and is called when we're navigating to a controller.
Rob gave the example of a user entering the url of step 2 of a wizard. You could catch this and force the user to finish step 1 first.

Everything in the new router is promise-based, so you can return a promise, but you can still return directly.

Finally, there are navigation commands with which you can take control of the router (for example to redirect the user somewhere).

Rob also went into the design of the router. Basically it's a navigation pipeline, a queue of navigation requests. It is possible to customize this pipeline by pulling out certain steps, or plugging in your own steps.

I'm happy Rob has joined the Angular team and with this new router, this move is already paying off.

Thursday, November 6, 2014

ngEurope: Protractor

At ngEurope, Julie Ralph and Chirayu Krishnappa gave an interesting presentation on Protractor. Protractor is a framework for end-to-end testing. The goal was not unit testing, because unit testing won't catch everything. Like so many of the projects in the Angular and javascript space, it is heavily under development, but the 1.0 release is planned for July 2015.

Protractor is implemented in NodeJS so you can write your tests in javascript. The most common way to run them is to use a local Selenium server. Tests can run in parallel and the primary syntax is the Jasmine syntax (with describe, beforeEach, it,...).

Protractor exports some globals to interact with the DOM. This is an example of getting the element that is data-bound (with Angular) to 'name' and entering some text:

element(by.model('name')) // get the <input ng-model="name" /> element
    .clear() // remove any text
    .sendKeys('abc'); // enter 'abc'

You can of course also search by id, class,...

Protractor includes filtering, clicking, setting text, and much more. As this is all done in javascript, you can (like in any other programming language) structure your code so you can reuse certain objects across different tests. An example could be a block of code that handles logging in.

Finally, it's important to note that Angular uses Protractor for its end-to-end tests, but the Protractor API is agnostic to Angular.

The session was short but it was enough to raise my interest. UI testing has always been hard, both in building tests and maintaing them. I'd have to test Protractor to see if it is any better, but I'm optimistic.

Wednesday, November 5, 2014

ngEurope: Angular Material

The Material design language is Google's design language for Android apps, presented at Google I/O last summer.

On a side note: if you take a look at some screenshots, you might say this has been inspired/copied from the Metro design language, with it's clean and modern look and feel. And you could be right. Personally, I couldn't care less. Companies and people copy from each other and are inspired by each other. Buy me a beer and we *would* have an animated (though polite) discussion :)

Of course, you could use these principles on other platforms (web, desktop, or even other mobile platforms), but it makes most sense on Android. Angular Material is the library you can use to leverage these principles in your Angular app. This makes it possible to use Angular to create an Android app, instead of the traditional Java-based approach.

This means Angular is now entering full steam into UI-country. Where most people will still think of Angular as an MV*-framework, it's actually much more than that. It's a fully-fledged front-end framework.

Personally, I find this an exciting evolution and I hope (and believe) Google will put their weight behind this. As Android is becoming for mobile what Windows has been for PCs, I would prefer to develop in HTML and javascript instead of Java (just personal preference).

There's lots to discover in Angular Material, so be sure to check out the demos. There are some things that stand out though:
  •  ng-subheader: subheaders that scroll up while you scroll, but are easily replace by the next subheader as you continue scrolling. Not-so-trivial to implement yourself!
  • tabs can be static or dynamically built, can be paged, can be controlled by the keyboard and are data-bindable
  • progressbars: lots of different kinds, no css for you anymore
  • forms: floating labels are a neat little usability feature (check out the link and empty one of the fields, then unfocus the element)
  • containers, flexbox, gutters, row layout, vertical alignment: it's all taken care of for you
  • last but definitely not least: ARIA. Accessibility is something that will have to get more and more attention as the web grows to be a bigger part of our lives.
All this is themeable and they're working hard on gesture based interactions, improved documentation, more animations and more samples.

At the moment of ngEurope, version 0.4 was out and any time now version 0.5 should come out. Starting with 0.5, they don't expect any more breaking changes. Beta 1 should be out before Q4 ends.

It's all open source and available on GitHub, Bower, or just material.angularjs.org

Friday, October 31, 2014

ngEurope: what's new in Angular 1.3?


Angular 1.3 provides us with some improvements over an already very decent framework. At ngEurope, the sessions were fast and intensive, which was an interesting approach, but also didn't allow for very many details. That being said, here are the points I noted.

$compileProvider.debugInfoEnabled(false);

This allows you to disable all the debugging info for the code you will deploy in production. Read more about it in the docs.

$httpProvider.useApplyAsync(true)

Normally, returning from an HTTP call will trigger Angular's $apply function. If you are doing several HTTP calls in succession, it might be interesting to only call the $apply function when they have finished. The useApplyAsync function gives you that possibility. Setting this to true will make Angular wait for HTTP calls that finish close together to finish, before calling $apply.

one-time binding (with ::)

Finally! One-time bindings allow you to make Angular forget about the binding once it has rendered it. This can improve performance, especially when you have a lot of bindings that no longer change once the result of the binding was rendered. Doing so is easy: just prefix your binding with '::', like so:

<span>{{::user.name}}</span>


Now, Angular will no longer track changes to this property

ng-model-options="{debounce: 500}

This waits 500ms before updating the binding. This can be useful when the updating of your binding could take a while.

ng-model-options="{updateOn: 'blur'}

If you've used WPF, this is the equivalent of UpdateSourceTrigger. The updateOn option accepts any javascript event and does just that: it updates the model when the given event is raised.

allOrNothing

The allOrNothing feature prevents Angular from making an HTTP request when it doesn't make any sense. For example this:

ng-src="users/{user.id}/avatar.png"

will not make an HTTP request if user or user.id is undefined.

Finally, ngMessages allows for easier validation messages.

So that is what I learnt from the session about Angular 1.3. It's just a quick overview, but it's good to know what's possible. When you're facing a particular situation, and you know Angular has a solution for it, you won't feel the need to implement a solution yourself. You can just go check out the documentation.