Just-Eat spectrum-bottom spectrum-top facebook google-plus instagram linkedIn pinterest reddit rss twitter_like twitter_reply twitter_share twitter_veriviedtwitter vimeo whatsapp youtube error_filled error file info-filled info loading star tick arrow arrowLeft arrowRight close download minus-filled minus move play plus-filled plus searchIcon settings

203 views

iOS Event tracking with JustTrack

Overview

At Just Eat, tracking events is a fundamental part of our business analysis and the information we collect informs our technical and strategic decisions. To collect the information required we needed a flexible, future-proof and easy to use tracking system that enables us to add, remove and swap the underlying integrations with analytical systems and services with minimal impact on our applications’ code. We also wanted to solve the problem of keeping the required event metadata up-to-date whenever the requirements change.

JustTrack is the event tracking solution we built for that and it’s available open source on Github at //github.com/justeat/JustTrack.

Examples and documentation are available in the Github repository Readme.

Main features

  • Events are declared in a .plist file and Swift 3 code is automatically generated at build time from it.
  • Events can be sent to multiple destinations (called Trackers) at the same time.
  • Custom Trackers are easy to create and use.

Events Definition

One of the problems we found with existing solutions is that the events are declared in code and therefore can only be maintained by developers. Similarly, existing solutions offer very generic tracking facilities for developers. Because of that, whenever the required metadata associated with an event changes for any reason, the developer has to search the code base and update all instances of the event with the correct implementation. This, of course, is a very fragile process and is prone to errors.

JustTrack solves these problems by declaring events in a plist file that is used to automatically generate equivalent definitions of the events in Swift that can be used in the app. This provides several benefits:

  • Each event is uniquely identified.
  • The metadata associated with each event is type checked.
  • When the requirements for an event change, the developers can see it through build errors and warnings that will naturally occur.
  • Plists can be edited as XML, which means anybody in the business can edit them.
  • It’s easy to search for events that are no longer used and deleted events won’t compile.

An Event is made of:

  • Name: the unique identifier
  • Registered Trackers: List of event destinations (e.g. Google Analytics)
  • Payload: The metadata associated with the event (at this time only String key-value pairs are supported)

Trackers

Another problem we found with existing solutions is that, generally speaking, all the events need to be tracked with the same Trackers. The developer doesn’t have any freedom to decide which event goes to which Tracker, and several solutions only support specific tracking technologies (such as GA, Firebase, and so on)

JustTrack solves this problem by allowing the developer to specify the “registered” trackers for each event and to create custom trackers.

A Tracker is an object implementing the JETracker protocol and is loaded using: tracker.loadCustomTracker( ... ) function. You can implement any tracker you want and JustTrack provides a few default trackers:

  • JETrackerConsole – print events to the system’s console
  • JEFacebookTraker (not yet implemented)
  • JEGoogleAnalyticsTraker (not yet implemented, Google’s pods can’t be used as a dependency in a pod)
  • JETrakerFirebase (not yet implemented, Google’s pods can’t be used as a dependency in a pod)

Conclusions

Using JustTrack you can easily track your app’s events to multiple destinations, having all the necessaire flexibility, intrinsic events documentation and all the expandability you will ever need in future, all of that writing the minimum amount of code possible.

About the author

Federico Cappelli is a Senior iOS Engineer and iOS COG Leader at Just Eat.

273 views

A better local and remote logging on iOS with JustLog

just_log_banner

In this blog post we introduce the solution for local and remote logging we developed for the Just Eat iOS app. It’s named JustLog and it’s available open source on Github at github.com/justeat/JustLog.

Overview

At Just Eat, logging and monitoring are fundamental parts of our job as engineers. Whether you are a back-end engineer or a front-end one, you’ll often find yourself in the situation where understanding how your software behaves in production is important, if not critical. The ELK stack for real-time logging has gained great adoption over recent years, mainly in the back-end world where multiple microservices often interact with each other.

In the mobile world, the common approach to investigating issues is gathering logs from devices or trying to reproduce the issue by following a sequence of reported steps. Mobile developers are mostly familiar with tools such as Google Analytics or Fabric.io but they are tracking systems, not fully fledged logging solutions.

We believe tracking is different in nature from logging and that mobile apps should take advantage of ELK too in order to take their monitoring and analysis to another level. Remote logging the right set of information could provide valuable information that would be difficult to gather otherwise, unveil unexpected behaviors and bugs, and even if the data was properly anonymized, identify the sequences of actions of singular users.

JustLog takes logging on iOS to the next level. It supports console, file and remote Logstash logging via TCP socket out of the box. You can also setup JustLog to use logz.io with no effort. JustLog relies on CocoaAsyncSocket and SwiftyBeaver, exposes a simple swifty API but it also plays just fine with Objective-C.

JustLog sets the focus on remote logging, but fully covers the basic needs of local console and file logging.

Usage

JustLog, is available through CocoaPods. To install it, simply add the following line to your Podfile:

Import it into your files like so:

This logging system strongly relies on SwiftyBeaver.
We decided to adopt SwiftyBeaver due to the following reasons:

  • good and extensible design
  • ability to upload logs to the cloud
  • macOS app to analyze logs

A log can be of one of 5 different types, to be used according to the specific need. A reasonable adopted convention on mobile could be the following:

  • 📣 verbose: Use to trace the code, trying to find one part of a function specifically, sort of debuggin with extensive information.
  • 📝 debug: Information that is diagnostically helpful to developers to diagnose an issue.
  • ℹ️ info: Generally useful information to log (service start/stop, configuration assumptions, etc). Info to always have available but usually don’t care about under normal circumstances. Out-of-the-box config level.
  • ⚠️ warning: Anything that can potentially cause application oddities but an automatic recovery is possible (such as retrying an operation, missing data, etc.)
  • ☠️ error: Any error which is fatal to the operation, but not the service or application (can’t open a required file, missing data, etc.). These errors will force user intervention. These are usually reserved for failed API calls, missing services, etc.

When using JustLog, the only object to interact with is the shared instance of the Logger class, which supports 3 destinations:

  • sync writing to Console (custom destination)
  • sync writing to File (custom destination)
  • async sending logs to Logstash (usually part of an ELK stack)

Following is a code sample to configure and setup the Logger. It should be done at app startup time, in the applicationDidFinishLaunchingWithOptions method in the AppDelegate.

The defaultUserInfo dictionary contains a set of basic information to add to every log.

The Logger class exposes 5 functions for the different types of logs. The only required parameter is the message, optional error and userInfo can be provided. Here are some examples of sending logs to JustLog:

It plays nicely with Objective-C too:

The message is the only required argument for each log type, while userInfo and error are optional.
The Logger unifies the information from message, error, error.userInfo, userInfo, defaultUserInfo and call-site info/metadata in a single dictionary with the following schema form of type [String : Any] (we call this ‘aggregated form’). E.g. in JSON representation:

All destinations (console, file, logstash) are enabled by default but they can be disabled at configuration time like so:

The above 5 logs are treated and showed differently on the each destination:

Console

The console prints only the message.

console

File

On file we store all the log info in the ‘aggregated form’.

Logstash

Before sending a log to Logstash, the ‘aggregated form’ is flattened to a simpler [String : Any] dictionary, easily understood by Logstash and handy to be displayed on Kibana. E.g. in JSON representation:

Which would be shown in Kibana as follows:

kibana

A note on Logstash destination

The logstash destination is configured via properties exposed by the Logger. E.g.:

When the logLogstashSocketActivity is set to true, socket activity is printed to the console:

socket_activity

This destination is the only asynchronous destination that comes with JustLog. This means that logs to Logstash are batched and sent at some point in future when the timer fires. The logstashTimeout property can be set to the number of seconds for the dispatch.
In some cases, it might be important to dispatch the logs immediately after an event occurs like so:

or, more generally, in the applicationDidEnterBackground and applicationWillTerminate methods in the AppDelegate like so:

Sending logs to logz.io

JustLog supports sending logs to logz.io.

At the time of writing, logz.io uses the following host and port (please refer to the official documentation):

When configuring the Logger (before calling setup()), simply set the token like so:

Conclusion

JustLog aims to be an easy-to-use working solution with minimal setup. It covers the most basic logging needs (console and file logging) via the great foundations given by SwiftBeaver, but also provides an advanced remote logging solution for Logstash (which is usually paired with Elasticsearch and Kibana in an ELK stack). JustLog integrates with logz.io, one of the most widely used ELK SaaS, placing itself as the only solution in the market (at the time of writing) to leverage such stack on iOS.

We hope this library will ease the process of setting up the logging for your team and help you find solutions to the issues you didn’t know you had.

About the author

Alberto De Bortoli is the Principal iOS Engineer at Just Eat.

498 views

Introducing JustPeek

JustPeek Banner

An iOS framework that ports Force-Touch Peek/Pop-like interactions to devices that aren’t force-touch enabled

At Just Eat, teams tend to build software with the community in mind. Over time, Just Eat has published several Open Source projects and has been an important pillar to the C# community.

More recently, the Company has grown its iOS team in London to focus on improving the Just Eat app for the UK market. With this growth phase, I had the opportunity to join the team for some time.

As part of the effort to improve our app, launch the new Just Eat brand and build modules to help us in the long run, we’re building and open sourcing more iOS projects than ever before. JustPeek, is the first of them to get published.

JustPeek is an iOS library that adds support for Force Touch-like Peek / Pop interactions on devices that don’t natively support it due to lack of force recognition capability in the screen. Under the hood it uses the native implementation if available, otherwise a custom implementation based on UILongPressGestureRecognizer. It fallbacks to the latter also on the iOS Simulator if needed.

Unlike similar libraries already available on the web, JustPeek tries to mimic entirely the original implementation. It doesn’t simply use screenshots to display a preview, but previews the UIViewController itself. As of version 0.2.0, it also supports committing to a preview in the fallback implementation. As there’s no way to measure pressure on old devices, committing happens when a user keeps the preview open for more than a certain amount of time – 3 seconds at the time of writing.

Here’s how you use JustPeek:

Here’s what it looks like in the demo application we ship with the code, as run on the iOS Simulator:

JustPeek Demo

We use JustPeek in the Just Eat UK app, in the list of results you get when searching for restaurants that serve your area, to show a preview of popular dishes a restaurant has to offer.

JustPeek is now publicly available on GitHub and can be added to your projects using CocoaPods. We really hope you’ll like it!

About the author

Gianluca Tranchedone is a Senior iOS Engineer and, at the time of writing, the main contributor of JustPeek.

983 views

Unit testing front-end JavaScript with AVA and jsdom

Writing tests for JavaScript code that interacts with the DOM can be tricky. Luckily, using a combination of AVA and jsdom, writing those tests becomes a lot easier.

This article will walk you through how to set everything up so you can get started writing your tests today.

What is AVA?

AVA is described as a “Futuristic JavaScript test runner“. Sounds fancy, huh?! So, what is it exactly that makes it “futuristic“?!

Tests run quickly

AVA runs test files in parallel, each in its own separate process, with the tests inside those files running concurrently. This offers better performance than other test runners that run tests serially, such as Mocha. This also means that each test file is run in an isolated environment — great for writing atomic tests.

Simple API

AVA’s API is very small because, in AVA’s own words, it is “highly opinionated“. You won’t find any assertion aliases here! This reduces the cognitive load required when writing tests.

Write tests in ES2015

You don’t need to do anything to be able to write tests in ES2015, AVA supports this out of the box! Under the covers it’s using Babel to transpile with the es2015 and stage-2 presets.

No implicit globals

AVA has no implicit globals, simply import it into your test file and you have everything you need.

Other benefits

There are a whole host of other benefits which AVA offers such as:

  • Promise support
  • Generator function support
  • Async function support
  • Observable support
  • Enhanced assertion messages
  • Clean stack traces

All of this combined sounds very “futuristic” to me!

Getting off the launchpad with AVA

Now that we know more about AVA, let’s create a new project and start writing some tests.

Start by running npm init inside a new project folder. This will create a package.json file, which will contain various pieces of information about the project such as its name, authors, and dependencies, among others. Hitting enter for each question will fill in a default value.

Installing AVA

Add AVA to the project by typing npm install ava --save-dev, then update the scripts section in package.json:

The --verbose flag enables the verbose reporter, which means more information is displayed when the tests are run.

When using npm scripts, the path to AVA in the node_modules folder will be resolved for us, so all we need to do is type npm test on the command line. Doing so at the moment this will give us an exception:

Let’s fix that by adding a test.

Writing a test

Create a test directory, with a file named demo.test.js inside, then add a test:

First, AVA is imported into the module, then the test function is called, passing a string as the first parameter which describes what the test is doing. The second parameter is the test implementation function which contains the body of the test, this provides us with an object, t, from which we can call the assertion functions.

The is assertion is used here, which takes two values and checks that they are both equal (using === so there is no type conversion).

Note: You can choose any name you like for the t parameter, such as assert. However, using the t convention in AVA will wrap the assertions with power-assert which provides more descriptive messages.

Run npm test and the test result will be printed out

Success! Our test passed as expected. To see an example of what a failing test would look like change the test assertion to t.is(1 + 1, 1). Run the test now and you’ll see an error

As you can see, there is a lot of useful information provided in order to help us track down the issue.

Testing modules

To demonstrate how to test a module, create a new folder called src in the root of the project with a file inside called demo-module.js with the contents:

Update demo.test.js by first importing the module, then adding a new test:

Running npm test now will give you the following exception

Uh oh, what happened?

AVA will transpile ES2015 code in your tests; however, it won’t transpile code in modules imported from outside those tests. This is so that AVA has zero impact on your production environment.

If our source modules are written in ES2015, how do we tell AVA that we’d like them to be transpiled too?

Transpiling source files

To transpile source files, the quick and dirty option is to tell AVA to load babel-register which will automatically transpile the source files on the fly. This is ok if you have a small number of test files, but there is a performance cost which comes with loading babel-register in every forked process.

The other option is to transpile your sources before running the tests in order to improve performance.

The next two sections look at how each technique can be achieved.

Transpile with babel-register

Add babel-register by running npm install babel-register --save-dev, then add a "babel" config to package.json

Next, add "babel-register" to the AVA "require" section

Run npm test and the tests will once again pass, great!

The recommendation from the AVA team is to use babel-registeruntil the performance penalty becomes too great“. As your test base grows you’ll need to look into setting up a precompilation step.

Setting up a precompilation step

A precompilation step will transpile your source modules before the tests are run in order to improve performance. Let’s look at one way to set this up.

Note: If you were following along with the last section you’ll need to remove the references to babel-register. First run npm uninstall babel-register --save-dev, then remove "babel-register" from the AVA "require" section in package.json.

Start by adding the babel-cli and babel-preset-es2015 packages to the project: npm install babel-cli babel-preset-es2015 --save-dev.

Next, add a "babel" config to package.json

In order to run the tests, we need to update the npm scripts. Add a new npm script called precompile

The precompile npm script will tell Babel to take the files in the src directory, transpile them, then output the results to the dist directory.

Next, the test npm script needs to be updated so that it runs the precompile step before running the tests

The double ampersand (&&) tells npm to first run the precompile script and then the AVA tests.

The final task is to update the reference to demo-module inside demo.test.js to point at the compiled code, we do this by replacing ../src with ../dist:

Run npm test and we’re presented with all green tests!

Testing the DOM using Node

So far we have the ability to test JavaScript code, but what if we’d like to test a function which makes use of the DOM? Node doesn’t have a DOM tree, so how do we get around this?

One option is to use a combination of a test runner and a browser — a popular combination is Karma and PhantomJS. These offer a lot of benefits like being able to test against real browsers, run UI tests, take screenshots, and the ability to be run as part of a CI process.

However, they typically come with a fairly large overhead, so running lots of small tests can take minutes at a time. Wouldn’t it be great if there was a JavaScript implementation of the DOM?

Welcome to the stage; jsdom!

jsdom

jsdom is described as “A JavaScript implementation of the WHATWG DOM and HTML standards, for use with Node.js“.

It supports the DOM, HTML, canvas, and many other web platform APIs, making it ideal for our requirements.

Because it’s purely JavaScript, jsdom has very little overhead when creating a new document instance which means that tests run quickly.

There is a downside to using a JavaScript implementation over an actual browser – you are putting your trust in the standards being implemented and tested correctly, and any inconsistencies between browsers will not be detected. This is a deal breaker for some, but for the purposes of unit testing I think it is a reasonable risk to take; jsdom has been around since early 2010, is actively maintained, and thoroughly tested. If you are looking to write UI tests then a combination of something like Karma and PhantomJS may be a better fit for you.

Integrating jsdom

Setting up jsdom can be a daunting task, the documentation is great, but very lengthy and goes into a lot of detail (you should still read it!). Luckily a package called browser-env can help us out.

Add browser-env to the project npm install browser-env --save-dev.

Create a helpers directory (which is ignored by convention when using AVA) inside test, then add setup-browser-env.js with the contents

We need to tell AVA to require this module before any of the tests are run so that browser-env can create the full browser environment before any DOM references are encountered. Inside your package.json add

Note: You may have noticed that this file is written in ES5. This is because AVA will transpile ES2015 code in the tests, yet it won’t transpile any modules imported or, in this case, required from outside the tests — see the transpiling source files section.

Testing the DOM

Let’s write a test which makes use of the document global which has been provided thanks to jsdom. Add a new test to the end of demo.test.js:

First, we add a paragraph element with some text to the document body, then query for that element using document.querySelector, and finally, we verify that the selected paragraph tag has an innerHTML value equal to 'Hello, world'.

Run the tests with npm test

Congratulations, you’ve just unit-tested the (virtual) DOM!

Test coverage with nyc

As a bonus let’s quickly set up some test coverage. Because AVA runs each test file in a separate Node.js process, we need a code coverage tool which supports this. nyc ticks the box — it’s basically istanbul with support for subprocesses.

Add it to the project with npm install nyc --save-dev, then update the test npm script by adding nyc before the call to ava:

You’ll also need to update the Babel config to tell it to include source maps when developing so that the reporter can output the correct lines for the transpiled code:

Run the tests and witness the awesome code coverage table!

What next?

If you’re interested in what else you can do with AVA, have a look through the AVA readme, check out the AVA recipe docs, read about common pitfalls, and listen to this JavaScript Air podcast episode. I’d also recommend looking into setting up linting for your code.

You can browse the source code for this blog post on GitHub.

So, now you have no excuse for not testing your front-end JavaScript!


Damian Mullins is a UI Engineer at Just Eat. Progressive enhancement advocate, web standards supporter, JavaScript enthusiast.

507 views

Angular in Paris – ng-europe 2016

In Product Research at Just Eat we aim to research, design and prototype rapidly. The more prototypes we can put in users’ hands, the more chance we’ll have of discovering a good idea. Hopefully we’ll do just that and start to iterate, but in reality most prototypes are binned. So the more we build, the more likely we are to find something that people want.

Angular could be a great fit for us, and the recent excitement around the Angular2 release meant it was high time for us to immerse ourselves in the community for a few days at ng-europe. Here’s a quick summary of the bits that jumped out for me along with some notes on things I plan to research.

The first day

I woke up quite early on my first morning in Paris and headed down to breakfast. Happily, Miško Hevery, who created Angular, and his Google colleague Alex Eagle were also awake, (I think they had jet lag). Over a serendipitous breakfast we talked about Angular but also about sugar, autonomous cars and the number of atoms in the universe. This was a good start!

Keynote

In his keynote to a packed hall Miško’s talked about how Angular has grown, both the community and the platform itself in its ambition and potential. It’s now everywhere: we can build Angular web apps, iOS and Android apps and desktop apps. Performance is hugely improved and experiences are native.

Things to research: Benchpress, Augury.

RxJS

Rob Wormald gave a standout talk on RxJS and observables, here are his slides. I really like his style, making a complex subject accessible. Observables have had a massive impact on Angular’s architecture, and would feature in many of the later talks.

Things to research: RxJS; using the switchMap operator in requests and in the router; avoiding the elvis operator in templates with smart and dumb components.

ng-bootstrap

The ng-bootstrap project powers Bootstrap 4 components natively with Angular2. Pawel Kozlowski described how, because they were especially written for Angular2, these components get the most from the framework. A good example is only rendering expensive content when it’s needed. Here are his slides.

(He talked about how well tested the components are, but he didn’t mention accessibility, a special interest — I looked at the repo and don’t worry, it’s well in hand!)

Things to research: components with observable children; components with a programmatic API; alternatives like Material.

Data science

Ari Lerner first plugged his company’s book (looks good, I’ve a sample to read, I’ll let you know) and then really caught my attention in his talk on data science.

At Just Eat we have access to huge amounts of rich data which we analyse intelligently to drive and validate change. Ari described pages that randomly reorder themselves until an optimal variation — one that best suited conversion goals — is found with machine learning. I couldn’t track Ari down to ask him more about this, I have a load of questions, I’ll try and find him tomorrow.

Things to research: this work (it’s open source, I’ll update with a link once I get one).

TypeScript

Live coding while public speaking goes badly wrong for some, but not for Daniel Rosenwasser. His talk on TypeScript was excellent, lots of smiles in the crowd. I already liked the idea of TypeScript (a superset of JavaScript) but had no idea of how awesome it has become, especially in combination with good tooling.

Daniel renamed a .js file to a .ts file then quickly worked through the compiler warnings and refactored into way more robust idiomatic TypeScript. He showed off some new features of which improved type inference really impressed, clever compiler.

Things to research: VS Code, the latest TypeScript.

The rest of day one

Other talks, all really interesting, covered BatScanner, unit testing, hybrid apps, security, migration and AngularFire2; all were recorded if you feel you’ve missed out. Looking forward to tomorrow!

The second day

Angular CLI

The day began with Hans Larsen reminding everyone that setting up tooling is really painful and robs way too much time from app development. Great to hear this isn’t just me.

The Angular team are taking this seriously. Angular CLI aims to stay out of your way, to understand your app and evolve with it by understanding your intent to generate, serve, test and build. You can generate classes, directives, enums, modules, pipes, services — and generation code adapts to its context. Here’s what it looks like:

Out of the box, Angular CLI can compile Less or Sass, transpile TypeScript, optimise assets, understand environments and serve a live reloading dev server. The compiler tree-shakes and compiles ahead of time, so the bundle is small and no renderer is needed on the client — users experience apps that load and render quickly.

Hans talked about the future, the CLI is getting smaller and more interoperable. Progressive web apps and server-side rendering will use ‘add-ons’ to change CLI behaviour. Add-ons and scripting will open the CLI to the community. I really like the fact that the CLI is part of Angular, it will always be in sync as Angular evolves. Learning just one tool is going to seriously speed up web app development.

Things to research: Angular CLI

Auguary

Vanessa Yuen showed us Augury, an open source Angular2 Chrome Extension built by Rangle.io and Google. Augury uses the debug API so that you can inspect and debug an Angular2 app in DevTools.

We watched as Vanessa used Augury to navigate an app’s component hierarchy, inspect state, change properties, invoke events, understand dependencies and view a router tree. One especially cool feature was using $a to reference a selected component in the console.

Augury looks pretty essential, especially when apps grow in complexity. Reassuring to hear how committed Rangle.io are to keep it in sync as Angular changes.

Things to research: Vanessa’s slides, Augury on GitHub.

Angular Universal

Next up, Wassim Chegham discussed Angular Universal: server-side rendering for Angular2. Not so relevant in product research, but still really impressive to hear about the latest.

SEO and link previews are the obvious problems that Universal solves for Angular apps. But more than that, it improves the user experience by removing the ‘web app gap’, the several seconds of blank screen a user experiences while an app bootstraps and renders. By rendering on the server the user sees the page immediately, before the app bootstraps. If they interact with the page before the app’s ready, those events are captured by Preboot until they may be safely replayed.

Things to research: Wassim’s slides, universal-starter seed.

The new router

Nir Kaufman gave us the lowdown on Angular2’s powerful root matching. This looks way easier to use with a consistent API and patterns. Lazy loading is new and as easy as replacing children with loadChildren. Params and query params now use observables which you pluck inside the component. It’s easier to secure states and prevent children activating or loading with ‘guards’. Especially cool, multiple views may now be serialised in the URL. I couldn’t quite get some of this talk, luckily Nir pointed us at some excellent guidance.

Things to research: Victor Savkin’s Articles and book.

Generative music

As a musician and someone who’s played around with music technology quite a bit, the talk by Tero Parviainen was by far the most entertaining and inspiring. Tero took us through his project In C, an Angular2 WebAudio app inspired by Terry Riley’s In C in which the user starts ‘players’ and advances them through patterns to produce a divergent generative composition.

Tero explained beautifully and with great clarity how Redux inspired the architecture of the app’s four decoupled component parts: a metronomic pulse, an immutable observable store, audio generation, and the UI. This architecture let him time travel through historic state and hot load code changes as he developed — awesome.

So no, this probably isn’t going to be relevant at work but just fantastic to see such a talent, much cheering and applause from everyone for Tero.

Things to research: Redux, ngrx/store.

Animation

Matias Niemelä discussed how animation in Angular2 uses a declarative domain specific language (DSL) inside the component. Testable, ahead-of-time compilable, independent from the DOM and web worker friendly.

This was the point in the conference when it really started to sink in for me what it means to for Angular to be platform agnostic. That was a nice moment, seriously impressive engineering.

The DSL composes states and transitions into triggers that are triggered from the component or from a property change in the template. For the web the implementation uses the Web Animations API — there’s a polyfill for lagging browsers.

Matias described a slew of upcoming features, a couple that jumped out were pulling animations from CSS and animating layout. I’m excited enough about playing around with what’s here today.

Things to research: Angular’s animation systemMatias’s slides.

Mobile apps

Adam Bradley from Ionic talked passionately about web standards and pointed out how fast and responsive the mobile web now is. Later, Christian Weyer and Thorsten Hans compiled the same codebase with Cordova and Electron yielding the same app across Mac OS, Windows, iOS, Android and web. Great talks but my issue with all these techniques is that apps don’t quite feel native enough, that you’re always dealing with web view’s shortcomings or chasing platform conventions and evolution.

So I was more interested in Marc Laval’s talk on custom renderers. In Angular2 the renderer is separated from Angular core and your app (in the browser they’re separated in the UI thread and a web worker). That renderer may be swapped so that Angular2 can work where there is no DOM, for example on Node, where Universal uses a server renderer, or on a mobile phone.

Both React Native and NativeScript work with Angular and render UIs natively with no web view. That’s a truly native experience and much more appealing to me. Neither need Angular to work, but how awesome would it be to master one framework for all three platforms?

Things to research: Marc’s slides, Angular2 &React Native, Angular2 & NativeScript.

Building RxJS

By now I was getting my head around observables, so André Staltz’s talk was well timed. Starting with an explanation of callback types, he flawlessly hacked away from simple JavaScript to a basic implementation of RxJS. He changed the code step-by-step, for example giveMeSomeData() became subscribe(). Really funny, and did the trick, definitely some lights going on all around.

Fast loading apps

Alex Eagle’s pointed at stats that give us about two seconds to make our apps responsive before users leave. At 2G or 250 kb/s that’s 500 k for JS and assets. That’s not very much so we need static analysis techniques, lazy loading, tree-shaking, bundling and minification to help us spend the budget.

As he dug into the complexity of these things I felt massively relieved that people as smart as Alex are figuring out how to do all this – even more relieved to learn that Angular CLI will take care of everything and I don’t need to worry.

Wrapping up

And that was it! It’s all recorded if you any of that piqued your interest. The Q&A at the end was really interesting. What most stuck with me was that AngularJS to Angular2 has been painful for everyone, but that this kind of upgrade won’t happen again. Angular2 is now a platform that will just grow in its power and reach as it shields us from turbulent and rapidly changing platforms.

Farewell Paris

Thanks ng-europe for a fascinating couple of days, it was great to spend time with such a friendly, smart and supportive community.


Ben Glynn is a Principal UI Engineer for Product Research at Just Eat. He’s passionate about product discovery, the user interface and user experience.