AngularJS Controllers: Patterns for successful use

This post summarizes a talk I gave at the AngularJS Meetup Berlin in October 2014.

Controllers are are a vital but widely misunderstood part of AngularJS. Thousands of clueless articles and very unfortunate examples in the official documentation are helping to spread confusion instead of clarity about the proper use of controllers.

I want to shed some light on the issue and present how we use controllers successfully in the Contentful user interface.

Continue...

Waddling Along

The world is not yet finished, but everyone is behaving as if everything was known. This is not true. In fact, the computer world as we know it is based upon one tradition that has been waddling along for the last fifty years, growing in size and ungainliness, and is essentially defining the way we do everything. My view is that today’s computer world is based on techie misunderstandings of human thought and human life. And the imposition of inappropriate structures throughout the computer is the imposition of inappropriate structures on the things we want to do in the human world.

Ted Nelson

Now, I want to add something to that and especially to the brilliant article I found that quote in. Something that is becoming increasingly clear to me over time.

I don't like technological change very much.

I don't like technology in itself, for its own sake.

I don't like to create things I don't need, to solve problems I wouldn't have if some other solution hadn't shaped those problems in the past.

I'm not looking for problems, not searching for them.

The ones that already present themselves are enough, and the technological issues are not the ones that matter.

In technology, almost nobody ever stops, looks back and tries to put the past into context. Everyone is always breaking new ground before understanding where we stand.

The question seems to always be "What can I do with this?", not "What problem does this solve?".

Now, while adventuring step by step into opportunities that present themselves as they appear is a sure way to make progress, but you won't be able to influence your direction very much. You run into danger of getting hopelessly lost or end up in a place you don't actually want to be.

By creating and creating myriads of aimless possibilities we're making the world unnecessarily more complex, losing ourselves in it at the same time.

The Desktop Metaphor

It's funny, lately I've been observing myself on multiple occasions sitting on the couch with three mobile devices: My Kindle, my iPad and my Phone, using them in parallel. A scene like this would not have raised any attention in Star Trek - the Next Generation, yet here it is being played out, in the reality of my living room.

picard-padds

So, this is our return from the round trip that has been the Personal Computer. The desk, as a workplace where you spatially arrange your documents to deal with them has been emulated by graphical operating systems inform of windows you could drag around and icons you would arrange on your screen.

The funny thing is, this has never actually really worked well. Unless you're on a Mac with a big screen, you are far more likely to run your applications in full screen and merely switching between them. (This is because a) Windows, as opposed to the Mac, never really encouraged developers or users to work with apps in windowed modes and b) Until, the advent of 24-inch monitors and higher pixel densities, there just wasn't enough room on the screen to display multiple apps in full fidelity at the same time.)

Now here I am, with three screens ("windows") in retina resolution of different sizes. On one I am reading a book. On the second I'm either taking notes or looking things up in a browser. On the third I'm exchanging a couple of words with a friend through instant messaging or send an email to someone I just realized I would really like to see over christmas.

This is the traditional Desktop, literally the Top of my Desk (ignore for the sake of the argument, that I'm actually on a couch. What's the difference even)? Just as before the personal computing revolution, I'm arranging different aspects of my work around me and interact with them individually, shifting my attention by grabbing one device and putting the other away.

This already works exceptionally well and there's no denying that this is the direction we're all headed. While I'm not convinced that the traditional computer with display, mouse and keyboard will ever disappear completely (Picard is still using one!), the future for most people will probably be a couple of independent tablets that are casually repurposed through software for whatever task is at hand.

The future is here. Over 300 years early.

10500200_3

Program Correctness

Demanding an absolute proof of correctness about a program is a noble but pointless exercise.

All you can prove is that a program adheres to a specification. Now what you have achieved is a shift of responsibility from the program to the spec.

And who's going to prove your spec correct? The more you streamline and automate this process, the more your spec becomes your program. You just invented a DSL, nice job.

This is not to say that formal proofs or reasoning about correctness are entirely worthless. Just that we should not expect them to do more than they are capable of.

Urbit

Nock is a stateless virtual machine defined in 200 words. The Nock machine is sealed - all execution is “pure.” Nock’s goal is extreme commoditization of computing semantics.

Hoon is a high-level language which defines itself in Nock. Its self-compiling kernel, 7000 lines of code, specifies Hoon unambiguously; there is no Hoon spec. Hoon can be classified as a pure, strict higher-order static type-inferred functional language, with co/contra/bivariance and genericity. However, Hoon does not use lambda calculus, unification, or other constructs from “PL theory.” Hoon also excels at handling and validating untyped data, a common task on teh Internets. Its syntax is entirely novel and initially quite frightening.

Arvo is a deterministic functional operating system defined in Hoon. While still basically a toy, it can serve web apps and network securely with other Arvo instances. An Arvo instance is designed to be a simple independent computer in the cloud.

Mindblowing stuff.

Giles Bowlett on Digital Literacy

This is, in my opinion, the strongest argument for seeing Unix and basic coding skills as fundamental required literacy today. As prostheses for memory and identity, computers are too useful not to use, but if you don't know how to craft your own code which gives you a UX which matches the way you think, you're doomed to matching the way you think to the available tools, and even the best available tools basically suck. Interaction design is not only incredibly hard to do well, it's also incredibly idiosyncratic.

Giles Bowkett - iOS fucked up my Brain

AngularJS: Views vs. Directives

In January I published a half-finished thought-piece on the old question of how to do nested views in AngularJS. That article was originally a reply to a thread on the AngularJS mailing list. In retrospect and after some feedback I want to elaborate on some points.

What was the problem again?

I argued that people should not look to views to build their app but make use of directives instead. Views are a mechanism, provided by AngularJS through the $route service to bind a URL to a controller instance and additional parameters as well as a Template that is injected into the DOM at a point designated by the ngView directive.

There is also the UI-Router module from Angular-UI that provides the ability to nest views inside of each other to allow a little more elaborate structures than Angular core. In UI-Router the directive that goes into the DOM is named uiView and "views" are called "states" and are a bit more powerful than Angular core view but largely it's the same concept.

Original Intention

Beginners coming to AngularJS are often confused about how to structure their Apps. AngularJS and the documentation provide little guidance in this regard and someone looking for answers will quickly stumble upon ngView and get the impression that it is the way to structure your app.

The original idea behind my post was to direct attention back to directives and to get people to use them for as many things as possible because in a lot of the documentation out there directives treated as last-resort-options for special cases when the opposite is true!

Directives are the core building block of an Angular app. Use them to insert whatever structure or behavior you need in your app. Views are merely a shortcut for very simple use-cases.

Capabilities of Views and Directives

There is no difference, everything you can do with nested directives, you can do with nested views

This is the main objection I received in response to the original post. The answer to this is both yes and no, depending on your situation. Let's first look at the case where it's yes:

This would be a fairly simple App without any fancy behavior beyond what is offered by AngularJS built-in directives. You can split your app into a small number of modules, likely representing CRUD behavior on a REST backend, a couple of lists, forms etc. The code required to attach your data to your scope fits neatly into the controllers for each view. You can derive the entire view state of your application from the URL and the data in your models.

This architecture breaks down as soon as your try anything more sophisticated. Imagine a couple improvements: For your lists, you want endless scrolling. To implement that you have to write a directive that generates a scrolling container, checks for the scroll position and reloads data as necessary. You might have some collapsible boxes containing filters for your list view and you want the dates in the table be displayed in relative terms.

The scroll position, the collapsed-state of the boxes are all part of your view state, but not necessarily something you want to encode in the URL. Tiny directives that update the DOM locally (keeping the relative timestamps up-to-date for example) are even something that can't be done at all with views. For performing tasks like this you need directives.

What's more important though, is the apps structure. Due to the nature of the DOM, your application is always a tree of components. The entirety of the data in your scopes determines which components are displayed and how they look and behave.

IMG_0050

The URL however is not a tree, it's a linear list, thus can only be used to store the state of the list of components from the app root to one leaf-node. You could have /appState/Astate/Bstate/Cstate or /appState/Astate/Bstate/Dstate but not meaningfully represent the states of both C and D in the URL.

(Smartass-Warning No 1: Of course you can throw in objections now that you could represent trees in a linear fashion or encode arbitrary byte strings in the URL and represent whatever you want there. But that's far beyond what $route/UI-Router offer.)

(Smartass-Warning No 2: You could also replace state in the URL with tuples of state (exactly what UI-Router calls "Multiple named views") whenever you have fixed tuples of components (C and D in the example), but that only holds as long as the tuples are predetermined. But if you do that you could also just treat them as a single component.)

View-Containers are meaningless, separated from their semantics through the routes.

The other, secondary gripe that I have with UI-Routers nested views is that they violate another core idea of AngularJS: Your DOM is the main place to describe the structure of your app. Reading a template should give you an idea of what goes where. If you want to edit a user, put a <edit-user user="user"/> directive into your template:

  • A reader will immediately see what that directive does and what data it depends on.
  • If you write the directive correctly it will be location independent, you can place it somewhere else in your app, as long as you pass in a user through the attribute it will work.

Using views litters you templates with meaningless containers, outsourcing the actual purpose of every view into the routes/states defined elsewhere. If you nest routes, the context of every view becomes implicit, it is harder to move them around and the only way to pass data into a view is through the scope.

An example for this scenario: suppose you have the user-editor <edit-user user="user"/>, it will be trivial to edit two users next to each other: <edit-user user="user1"/><edit-user user="user2"/> and a few lines of CSS to arrange them visually and you're done.

But URLs make the web what it is, you do want to bind your application state to the URL!

If you rely solely on the URL to store your application state you limit the complexity of what you can store. This is not necessarily bad! Quite the contrary, the simpler your app the better. But be aware of the limitations and implications of your architecture and make decisions like these consciously.

Also, embrace directives, they're cool.

Directives are cool.

AngularJS Meetup Berlin – Expectations and the Future

In April 2013 I initiated the first AngularJs Berlin Meetup at co.up, followed by two other meetups in May and June. Although the first meetup attracted quite a lot of people, the next two left me with a mixed feeling.

My original idea was very simple: find other AngularJS developers to exchange ideas and experiences. Unfortunately most of the people that showed up had no former AngularJS experience.

That's not a bad thing at all! Quite the opposite: I love passing my enthusiasm for the framework to others. But this leaves me in a tough sport for the meetups:

I don't want to give an introductory talk every time. I gave one during the first meet up and another one at the apps.berlin.js meeting in June. On the other hand, I don't want to bore beginners with endless discussions about advanced techniques or very specific problems.

AngularJS as a topic is too specific to have talks and presentations at every meetup. I'd rather keep it as what I originally had planned: an informal get-together to discuss Angular's design, solve specific problems, answer questions to beginners or just exchange ideas about web development in general.

Maybe all I need to do is to communicate this concept better to help people have a better idea what to expect.

I would like to get some feedback from you on this? What directions should the AngularJS meetup take in the future? Please leave comments below:

AngularJS Talk apps.berlin.js May 2013

During the apps.berlin.js in May i gave yet another, more simplified introduction to AngularJS. In that talk I created a short Todo-Application using Hoodie as a persistence backend, showing the vary basic elements used to assemble an application.

The example app for that talk is at http://github.com/janv/yatl, the slides are available here: AngularJS Example.

Code Literacy oder Digitaler Alphabetismus

Der folgende Text ist eine deutsche Übersetzung von Why Coding is and is Not The New Literacy die ich für das Code Literacy Blog geschrieben habe. Hier fehlt das Originalzitat von Pierce Gleeson, der nur auf Englisch im ursprünglichen Post vorliegt und ohne den der erste Absatz einwenig den Bezug verliert.

Wenn Menschen im Zusammenhang mit Programmierung von "Code Literacy" oder "digitalem Alphabetismus" sprechen, ist damit nicht gemeint dass Programmieren eine dem Lesen und Schreiben ähnliche Grundfähigkeit ist, sondern dass Programmieren die Beherrschung von Schriftsprache als Unterscheidungsmerkmal der intellektuellen Elite ersetzt.

Damit diese Argumentation nachvollzogen werden kann ist es nötig, zunächst den Begriff des Programmierens zu klären. Das wesentliche ist nämlich nicht, in der Lage zu sein, tatsächlich Computerprogramme zu schreiben. Wichtiger ist, ein Verständnis dafür zu entwickeln wie Algorithmen Informationen verarbeiten, wie unsere Welt zunehmend von Maschinen und abstrakten mathematischen Modellen geformt und gelenkt wird, kleinen hochspezialisierten Teilen die nach strengen Regeln zusammenarbeiten um neue, mächtigere Fähigkeiten zu entwickeln.

Wenn das Studium der Informatik mich eines gelehrt hat, dann Probleme in ihre Teile zu zerlegen und nebensächliches vom wesentlichen zu trennen, bis sich die Essenz offenbart und sich die Lösung fast von selbst präsentiert. Genau dies ist die wichtigste Fähigkeit der Informatiker. Ist diese Denkweise einmal verinnerlicht verändert für immer die Herangehensweise an Probleme jeder Art.

So gut wie jeder kann heute lesen und schreiben, aber nur wenige Menschen verfügen über allgemeine Fertigkeiten zur Lösung von Problemen. Programmieren ist im Grunde nichts anderes als das: formalisiertes und strukturiertes Analysieren und Lösen von Problemen, kombiniert mit eher unwesentlichem Hintergrundwissen über die Syntax der Programmiersprache in der man sich gerade bewegt. Um Programmieren zu können braucht man daher eigentlich keine Ausbildung als Softwareentwickler. Jeder der schonmal mit Excel gearbeitet hat, hat schon programmiert, vielleicht ohne es zu wissen.

Theoretisch in der Lage sein etwas tun zu können und es tatsächlich zu tun sind zwei sehr verschiedene Dinge. In diesem Fall ist es wichtiger, theoretisch und allgemein zu verstehen was beim Programmieren vor sich geht, nicht die praktische Erfahrung aus Jahren in der Softwareentwicklung. Dieses Verständnis kommt fast von allein wenn man sich mit strukturiertem Denken beschäftigt, sei es in der Wissenschaft oder der Geschäftswelt.

Es lässt sich kaum verleugnen dass in einer Gesellschaft die besessen von Informationen und Effizienz ist, Menschen die Probleme lösen und Systeme durchschauen können einen wesentlichen Vorteil haben, so wie es in der Vergangenheit Menschen mit Schriftkenntnis gegenüber Analphabeten hatten.