Angular 4.2.0 is here!

Angular logo

Templates

As we explained in our blog post about Angular 4.1, it is now possible to use strictNullChecks in your applications.

The ! post-fix operator is now also available in templates:

<h2>{{ possiblyNullRace!.name }}</h2>

The code generated from the AoT compiler will then include the non-null assertion operator too, allowing to do strict null checking in your templates also!

Forms

Two new validators joins the existing required, minLength, maxLength, email and pattern: min and max help you validate that the input is at least or at most the value specified.

<input type="number" [(ngModel)]="user.age" min="0" max="130">

Update (2017-06-17): The min and max validators have been temporarily removed from Angular in version 4.2.3, as they are a breaking change. They’ll return in a major version, maybe 5.0.0.

Animations

Animations received a lot of love in this release!

A new query function has been introduced in the animation DSL, allowing to query elements in the template. It uses querySelectorAll behind the scene, so you can use an element or a class as parameter for example. It also supports pseudo-selectors, and that opens a few interesting possibilities!

For example, we can now easily animate elements in a NgFor:

<div [@races]="races?.length">
  <button class="btn btn-primary mb-2" (click)="toggle()">Toggle</button>
  <div *ngFor="let race of races | slice:0:4">
    <h2>{{race.name}}</h2>
    <p>{{race.startInstant}}</p>
  </div>
</div>

with the following animation:

trigger('races', [
  transition('* => *', [
    query(':leave', [
      animate(1000, style({ opacity: 0 }))
    ], { optional: true }),
    query(':enter', [
      style({ opacity: 0 }),
      animate(1000, style({ opacity: 1 }))
    ], { optional: true })
  ])
])

Now, every time an element will leave (removed from the races array), it will slowly fade out. And when an element enters, it will slowly fade in.

Query animation

Another function introduced is stagger. it allows to build a staggering animation, where the elements will animate one after the other.

trigger('races', [
  transition('* => *', [
    query(':leave', [
      stagger(500, [
        animate(1000, style({ opacity: 0 }))
      ])
    ], { optional: true }),
    query(':enter', [
      style({ opacity: 0 }),
      animate(1000, style({ opacity: 1 }))
    ], { optional: true })
  ])
])

Stagger animation

animation has also been added to build reusable animations. The syntax allows to have dynamic parameters with default values. When you then need to use a reusable animation, you can call useAnimation, and override the default parameters if you want to.

In our small example, we can for example define a changeOpacity animation:

const changeOpacity = animation(
  [animate(1000, style({ opacity: '{{opacity}}' }))],
  { params: { opacity: 0 } }
);

This animation will slowly transition to the defined opacity (by default 0). Then we can use this animation:

trigger('races', [
  transition('* => *', [
    query(':leave', [
      stagger(500, [
        useAnimation(changeOpacity)
      ])
    ], { optional: true }),
    query(':enter', [
      style({ opacity: 0 }),
      useAnimation(changeOpacity, { params: { opacity: 1 } })
    ], { optional: true })
  ])
])

You can give various options to the useAnimation, like the delay you want to apply or the duration.

Note that when an element is animating, Angular will add a ng-animating class on the element. You can customize your CSS to use it, or you can use the pseudo-selector :animating in a query to style these elements.

It’s now also possible to trigger “child” animations, with the animateChild function. It can be handy to animate the router transitions for example.

Last but not least, we can now inject AnimationBuilder in our components, to programmatically build animations, and trigger them on demand from the code.

Tests

TestBed.overrideProvider()

The team is also working on the internals to bring interesting features, like the possibility to test in AoT mode. This materializes in this release with a new method on TestBed called overrideProvider, that allows to override a provider, no matter where it was defined (whereas you currently have to know the module/component that declared the provider you want to override).

This is a small step to have the same features between tests in JiT mode and in AoT mode. And this is really interesting for developers, as currently you can only test in JiT mode, which can lead to discrepancies. Indeed you can have an app that runs perfectly, and no error in your unit tests, and then try to build the app with the AoT compiler, and see a bunch of errors. In a near future, we will be able to test in AoT mode too, so you’ll be sure that your app runs fine in both modes.

If you want to learn more on this topic, take a look at the official design doc.

The AoT compiler will also become incremental soon, allowing to use it during development. Even if it is possible to use it right now when you’re coding, it’s too slow for most applications, as every change triggers a full rebuild of the application.

flush()

Another utility function called flush has been added. You may know that Angular comes with a built-in support for asynchronous tests.

For example, let’s say you have a component which displays a welcome message after a few seconds:

@Component({
  selector: 'pr-welcome',
  template: '<p>{{ greetings }}</p>'
})
export class WelcomeComponent implements OnInit {

  greetings: string;

  ngOnInit() {
    setTimeout(() => this.greetings = 'Hello there!', 3000);
  }

}

After 3 seconds, the greetings field will be initialized and the template will be updated.

Now how do you test this?

The first time you encounter something like this, you may be tempted to write a naive test, like waiting for 3 seconds before testing the content of the template:

it('should have a greeting message', () => {
  const fixture = TestBed.createComponent(WelcomeComponent);
  const element = fixture.nativeElement;
  fixture.detectChanges();

  setTimeout(() => {
    fixture.detectChanges();
    const message = element.querySelector('p').textContent;
    expect(message).toBe('Hello there!');
  }, 3000);
});

This will succeed… for the wrong reasons! It will indeed always succeed, as Jasmine will simply exit the test without running the assertions inside the setTimeout.

Angular offers the async function to wrap your test and force Jasmine to wait for the asynchronous functions in your test to finish:

it('should have a greeting message', async(() => {
  const fixture = TestBed.createComponent(WelcomeComponent);
  const element = fixture.nativeElement;
  fixture.detectChanges();

  setTimeout(() => {
    fixture.detectChanges();
    const message = element.querySelector('p').textContent;
    expect(message).toBe('Hello there!');
  }, 3000);
}));

This time the test succeeds for the right reasons. But we now have a test that needs 3 seconds to execute…

Angular allows you to do much better by using fakeAsync and tick. fakeAsync is used to wrap your test into a zone where you master the time! And tick can be used to fast-forward the time for as many milliseconds as you want. We can write the same test with these two like this:

it('should have a greeting message', fakeAsync(() => {
  const fixture = TestBed.createComponent(WelcomeComponent);
  const element = fixture.nativeElement;
  fixture.detectChanges();

  tick(3000);
  fixture.detectChanges();
  const message = element.querySelector('p').textContent;
  expect(message).toBe('Hello there!');
}));

The test is now instantaneous and can be read as if everything is synchronous!

You still need to know how long to wait in your test, and that’s where the new flush function can help. You can use flush instead of tick and the test will automatically wait until all macrotask events (like timeout) have been cleared from the event queue:

it('should have a greeting message', fakeAsync(() => {
  const fixture = TestBed.createComponent(WelcomeComponent);
  const element = fixture.nativeElement;
  fixture.detectChanges();

  flush();
  fixture.detectChanges();
  const message = element.querySelector('p').textContent;
  expect(message).toBe('Hello there!');
}));

fixture.whenRenderingDone()

A method called whenRenderingDone has also been added to the ComponentFixture class. It returns a promise and is slightly similar than whenStable but focuses on waiting the animations to be done. As you can imagine, it will be really useful if you need to test components with animations.

Summary

That’s all for this release! The focus was mainly on animations and tests, and the team is also working on reducing the bundle size of our applications, with the help of the Google Closure Compiler. I think we’ll learn more about that very soon!

In the meantime, all our materials (ebook, online training (Pro Pack) and training) are up-to-date with these changes if you want to learn more!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Angular 4.1.0 is here!

Angular logo

This will be a short blog post, because there are not a lot of new features…

The most part of the work has been done on the official docs, which are now an Angular CLI app, and this migration takes some time. We can then expect to have nice new content when this will be done.

So, what are the new features? Let’s dive in!

i18n

The internationalization module has a few bugfixes, and a notable new feature: the extracted messages file now has the source file for each message. It will be far easier for developers to know where the messages come from!

<trans-unit id="home.title" datatype="html">
  <source>Welcome to Ponyracer</source>
  <target/>
  <context-group purpose="location">
    <context context-type="sourcefile">src/app.component.ts</context>
    <context context-type="linenumber">10</context>
  </context-group>
</trans-unit>

Core

The main new feature of this release is the support of the brand new TypeScript 2.3 version, and the support of strictNullChecks.

This option allows to check if you won’t run into nullability problems in your app. Angular itself now has correct types. For example, when you try to retrieve a FormControl from a FormGroup with get, the returned type is AbstractControl | null.

That’s because the control you are trying to get might not exist, and, if you are not careful, you are introducing a bug in your application by supposing it does exist.

If you don’t have the strictNullChecks option, you can do:

static passwordMatch(control: FormGroup) {
  const password = control.get('password').value;
}

but when you enable it, the compiler will complain, and may save you by warning you that the control may not exist, and that your code should handle this case.

You have to do something like:

static passwordMatch(control: FormGroup) {
  const passwordCtrl = control.get('password');
  const password = passwordCtrl !== null ? passwordCtrl.value : '';
}

Or you can use the ! post-fix expression operator introduced by TypeScript, to basically say to the compiler “Shut up”:

static passwordMatch(control: FormGroup) {
  const password = control.get('password')!.value;
}

It can also be really interesting for your application models. Let’s say you have a UserModel representing your user, with a surname field that can be null. If you declare it correctly, the type should be:

interface UserModel {
  surname: string|null;
}

Then, with the strictNullChecks option activated, the compiler will help you when you use this model. For example:

this.user.surname.toLowerCase();

will throw a warning as the surname field can be null.

When you have complex entities coming from your server, it can really help you to have this kind of warning to avoid subtle and hard to avoid bugs.

That’s all for this small release!

All our materials (ebook, online training (Pro Pack) and training) are up-to-date with these changes if you want to learn more!

Oh, and our Pro Pack has 3 new exercises about the router! A perfect way to learn about protecting routes with guards, nested routes, resolving data before displaying the component, and how to split your app in small chunks that can be lazy-loaded.


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


🎉 Here we are, Angular 4.0.0 is out, right on schedule ! 🎉

Angular logo

Technically there are some breaking changes, explaining that’s why the major version number has changed. And, if you missed it, there is no Angular 3: the router package was in version 3.x, so instead of bumping everything to 3.0 and the router to 4.0, the team chose to bump everything to 4.0.

The breaking changes are quite limited though, we updated several of our apps in a few minutes: nothing too scary.

TypeScript 2.1+ is now required (it was 1.8+ before), and some interfaces have changed or are deprecated (rarely used in most applications, like OpaqueToken or SimpleChange).

TypeScript 2.1 and 2.2 have brought really nice features you should check out. Angular 4 now supports them (and you will soon be able to activate the new strictNullChecks TypeScript option for example).

So what does this new Angular version bring? Let’s dive in!

Ahead of Time compilation - View Engine

This is probably the biggest change, even if, as a developer, you will not see the difference.

As you may know, in AoT mode, Angular compiles your templates during the build, and generates JavaScript code (by opposition to the Just in Time mode, where this compilation is done at runtime, when the application starts).

AoT has several advantages: it errors if one of your templates is incorrect at build time instead of having to wait at runtime, and the application starts faster (as the code generation is already done). You also don’t have to ship the Angular compiler to your users, so, in theory, the package size should be smaller. In theory, because the downside is that the generated JS is generally bigger than the uncompiled HTML templates. So, in the vast majority of applications, the package is in fact bigger with AoT.

The team worked quite hard to implement a new View Engine, that produces less code when you use the Ahead of Time compilation. The results are quite impressive on large apps, while still conserving the same performances.

To give you a few numbers, on two medium apps we have, the bundle sizes went:

  • from 499Kb to 187Kb (68Kb to 34Kb after gzip)
  • from 192Kb to 82Kb (27Kb to 16Kb after gzip)

That’s quite a big difference!

Interesting to note that in the design doc, the Angular team compares the performance (the execution time of course but also the pressure on the memory) with the baseline implementation (best vanilla JS they could write) Angular 2.x and InfernoJS (a really fast React-like implementation).

Universal

A ton of work has also been done on the Universal project which allows you to do server-side rendering. The project was mainly maintained by the community until now, but, starting with this release, it’s now an official Angular project.

Animations

Animations now have their own package @angular/platform-browser/animations (one of the things you may have to change when you update). This means the bundle you ship to your users will not include useless code if you don’t use animations in your app.

Templates

template is now ng-template

The template tag is now deprecated: you should use the ng-template tag instead. It still works though. It was a bit confusing as template is a real HTML tag that Web Component can use. Now Angular has its own template tag: ng-template. You will have a warning if you use the deprecated template somewhere when you update to Angular 4, so it will be easy to spot them.

ngIf with else

It’s now also possible to use an else syntax in your templates:

<div *ngIf="races.length > 0; else empty"><h2>Races</h2></div>
<ng-template #empty><h2>No races.</h2></ng-template>

as

Another addition to the template syntax is the as keyword, to simplify the let syntax. It allows to store a result in a variable of the template, to use it in the element.

It can be useful to store a sliced collection for example:

<div *ngFor="let pony of ponies | slice:0:2 as total; index as = i">
  {{i+1}}/{{total.length}}: {{pony.name}}
</div>

Or even more useful, to subscribe only once to a pipe with async. If race is an observable, instead of the bad and ugly:

<div>
  <h2>{{ (race | async)?.name }}</h2>
  <small>{{ (race | async)?.date }}</small>
</div>

you can now use the good:

<div *ngIf="race | async as raceModel">
  <h2>{{ raceModel.name }}</h2>
  <small>{{ raceModel.date }}</small>
</div>

Pipes

Titlecase

Angular 4 introduced a new titlecase pipe. It changes the first letter of each word into uppercase:

<p>{{ 'ninja squad' | titlecase }}</p>
<!-- will display 'Ninja Squad' -->

Http

Adding search parameters to an HTTP request has been simplified:

http.get(`${baseUrl}/api/races`, { params: { sort: 'ascending' } });

Previously, you had to do:

const params= new URLSearchParams();
params.append('sort', 'ascending');
http.get(`${baseUrl}/api/races`, { search: params });

Test

Overriding a template in a test has also been simplified:

TestBed.overrideTemplate(RaceComponent, '<h2>{{race.name}}</h2>');

Previously, you had to do:

TestBed.overrideComponent(RaceComponent, {
  set: { template: '<h2>{{race.name}}</h2>' }
});

Service

Meta

A new service has been introduced to easily get or update meta tags:

@Component({
  selector: 'ponyracer-app',
  template: `<h1>PonyRacer</h1>`
})
export class PonyRacerAppComponent {

  constructor(meta: Meta) {
    meta.addTag({ name: 'author', content: 'Ninja Squad' });
  }

}

Forms

Validators

One new validator joins the existing required, minLength, maxLength and pattern. email helps you validate that the input is a valid email (good luck finding the correct regular expression by yourself).

Compare select options

A new directive has been added to help you compare options from a select: compareWith.

<select [compareWith]="byId" [(ngModel)]="selectedPony">
   <option *ngFor="let pony of race.ponies" [ngValue]="pony">{{pony.name}}</option>
</select>

byId(p1: PonyModel, p2: PonyModel) {
   return p1.id === p2.id;
}

Router

ParamMap

A new interface has been introduced to represent the parameters of a URL: ParamMap. Instead of using params or queryParams, you should now use paramMap or queryParamMap, because they offer the choice between get() to get a value, or getAll() to get all values (as query parameters can have multiple values for example).

const id = this.route.snapshot.paramMap.get('ponyId');
this.ponyService.get(id).subscribe(pony => this.pony = pony);

or as an Observable:

this.route.paramMap
  .map((params: ParamMap) => params.get('ponyId'))
  .switchMap(id => this.ponyService.get(id))
  .subscribe(pony => this.pony = pony);

CanDeactivate

The CanDeactivate interface now has an extra (optional) parameter, containing the next state (where you are going to navigate). You can now implement clever logic when your user navigates away from the current component, depending on where he/she is going.

I18n

The internationalization is slowly improving with tiny things. For example, ngPlural is now simpler:

<div [ngPlural]="value">
  <ng-template ngPluralCase="0">there is nothing</ng-template>
  <ng-template ngPluralCase="1">there is one</ng-template>
</div>

compared to what we had to write:

<div [ngPlural]="value">
  <ng-template ngPluralCase="=0">there is nothing</ng-template>
  <ng-template ngPluralCase="=1">there is one</ng-template>
</div>

We added a complete chapter on internationalization in our ebook, with several use cases and best practices described if you want to learn more about i18n!

Summary

This release brings some nice features and a really welcome improvement of the generated code size, for the price of very few breaking changes that should not impact you a lot. The migration has been quite smooth for us.

All our materials (ebook, online training (Pro Pack) and training) are up-to-date with these changes if you want to learn more!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


New month, new minor release of Angular! December is the month of the last 2.x releases, because the next one will be… Angular 4! If you missed the official announcement (Igor Minar’s keynote), let me sum it up for you.

We’ll have a major release every six months, according to the plan. The next major release is planned for March 2017. It should have been Angular 3, but the Angular router is already with a version number in 3.x (because it has been rewritten several times during Angular development). So to avoid trouble, everything will be bumped to 4.x! Angular 3 will never exist, Angular 4 is the next one, with Angular 5 just around the corner. And now the framework should be called just “Angular”.

Don’t worry, these releases are not a complete rewrite with no backward compatibility like Angular 2 was. They will maybe contain deprecations and new APIs. Technically Angular 4 is a new major release because it contains a breaking change: the minimum version of TypeScript, if you use it, will be 2.1, whereas the current minimum version is 1.8. Nothing too scary.

Back to our 2.3 and 2.4 releases: what’s new in these small releases?

Language service

One of the most exciting feature is not really in Angular itself, but this release contains a new module that will be reaaaaally handy: a language service module. This is really similar to what TypeScript offers. A language service allows the IDEs to provide great autocompletion. It’s basically an API that the IDE can call to ask “what smart thing can I suggest at this position in this file?”.

That unlocks the possibility to have smart autocompletion in templates for example (something the IDEs are not currently great at).

There is already a VS Code plugin that you can try here, and JetBrains already announced they will include it in their next release (2017.1).

Here is how it works in VS Code:

Inheritance

You can now use inheritance in your apps.

You already could but the decorators from the parent were ignored: now, the “last” decorator (when you list them in the ancestor first order) of each kind will be applied.

@Component({ selector: 'ns-pony'})
export class ParentPony {}

// will use the parent decorator
export class ChildPony extends ParentPony {}

// will use its own decorator
@Component({ selector: 'ns-other'})
export class OtherChildPony extends ParentPony {}

If you define the same decorator on the child, this decorator will be used (there is no fancy property merging from the parent and the child).

If a class inherits from a parent class and does not declare a constructor, it inherits the parent class constructor, meaning that the dependency injection will be properly done in the parent class.

The lifecycle hooks defined in the parent class will also be called properly, unless they are overridden in the child class:

export class ParentPony implements OnInit {
  ngOnInit() {
    console.log('will be called');
  }
}

// the parent `ngOnInit` will be called
@Component({ selector: 'ns-pony'})
export class ChildPony extends ParentPony {}

Route reuse strategy

The Angular router tries to optimize a few things for you, especially when you navigate from a route to itself: when you go from races/12 to races/13, the router will reuse the RaceComponent (instead of destroying it and recreating it). This is powerful, but you then need to subscribe to an observable from the router to know when the parameters change, to display the correct race for example.

This is still the default behavior, but you can now turn it off, and ask the router to destroy and recreate your component every time, by implementing a RouteReuseStrategy.

See you next year to dig in the new releases, and the upcoming Angular 4!

Check out our ebook and Pro Pack if you want to learn more about Angular!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


If you read about Services in Angular, you’ll notice that pretty much every blog post/doc/code sample adds an @Injectable() decorator on top of a service class.

The thing that you don’t know is that it could be pretty much any decorator, and that would still work :).

Let’s take an example:

@Component({
  selector: 'ponyracer-app',
  template: '<h1>PonyRacer</h1>'
})
export class PonyRacerAppComponent {
  constructor(private appService: AppService) {
    console.log(appService);
  }
}

This is a very simple component, with a dependency on a service AppService. The service looks like:

export class AppService {
  constructor() {
    console.log('new app service');
  }
}

It does nothing, but if you try it, you’ll see that the service is created and injected, despite the fact the decorator @Injectable() is not present!

Why does that work? Let’s check the JavaScript generated from these TypeScript classes:

var AppService = (function () {
    function AppService() {
      console.log('new app service');
    }
    return AppService;
}());
exports.AppService = AppService;

I skipped a bit of generated code to focus on the interesting part. The class AppService generates a pretty simple JavaScript. Let’s compare that to the PonyRacerAppComponent class:

var PonyRacerAppComponent = (function () {
    function PonyRacerAppComponent(appService) {
        this.appService = appService;
        console.log(appService);
    }
    PonyRacerAppComponent = __decorate([
        core_1.Component({
            selector: 'ponyracer-app',
            template: '<h1>PonyRacer</h1>'
        }),
        __metadata('design:paramtypes', [app_service_1.AppService])
    ], PonyRacerAppComponent);
    return PonyRacerAppComponent;
}());

Wow! That’s much more code! Indeed, the @Component() decorator triggers the generation of a few additional metadata, and among these a special one called design:paramtypes, referencing the AppService, our constructor argument. That’s how Angular knows what to inject in our Component, cool!

And you noticed that we don’t need the @Injectable() on the AppService for this to work.

But let’s say that now, our AppService has a dependency itself:

export class AppService {
  constructor(http: HttpService) {
    console.log(http);
  }
}

If we launch our app again, we’ll now have an error:

Error: Can't resolve all parameters for AppService: (?).

Hmm… Let’s check the generated JS:

var AppService = (function () {
    function AppService(http) {
        console.log(http);
    }
    return AppService;
}());
exports.AppService = AppService;

Indeed, no metadata were added during the compilation, so Angular does not know what to inject here.

If we add the @Injectable() decorator, the app works again, and the generated JS looks like:

var AppService = (function () {
    function AppService(http) {
        console.log(http);
    }
    AppService = __decorate([
        core_1.Injectable(),
        __metadata('design:paramtypes', [http_service_1.HttpService])
    ], AppService);
    return AppService;
}());
exports.AppService = AppService;

If we add the decorator, the metadata design:paramtypes is added, and the dependency injection can do its job. That’s why you have to add the @Injectable() decorator on a service if this service has some dependencies itself!

But the funny thing is that you could add any decorator. Let’s build our own (useless) decorator:

function Foo() {
  return (constructor: Function) => console.log(constructor);
}

@Foo()
export class AppService {
  constructor(http: HttpService) {
    console.log(http);
  }
}

The @Foo() decorator does not do much, but if we check the generated JS code:

var AppService = (function () {
    function AppService(http) {
        console.log(http);
    }
    AppService = __decorate([
        Foo(),
        __metadata('design:paramtypes', [http_service_1.HttpService])
    ], AppService);
    return AppService;
}());
exports.AppService = AppService;

Wow, the metadata were generated! And indeed, the app still work perfectly!

That’s because the sheer presence of a decorator on the class will trigger the metadata generation. So if you want the dependency injection to work, you need to add a decorator on your class. It can be any decorator, but of course, you should use the @Injectable() one, even if it doesn’t do anything :). The best practice is to add it on every service, even if it doesn’t have any dependencies on its own.

Check out our ebook and Pro Pack if you want to learn more about Angular!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Le jeudi 24 novembre 2016, Agnès Crépet et Cyril Lacote assuraient la keynote d’ouverture de Codeurs en Seine 2016 : Codeurs du Monde.
L’équipe d’organisation leur avait demandé de raconter l’expérience de leur tour du monde.

La vidéo

La vidéo, avec slides synchronisés, est disponible chez InfoQ.

Si vous préférez la lecture, en voici la retranscription complète.



La retranscription

Cette diapositive de titre devient extrèmement cocasse quand on réalise qu’elle montre des développeurs Java sur l’île de Java. Ha ha.

Que racontent Agnès Crépet et Cyril Lacote ?

Agnès Crépet est développeuse, Java Champion, membre active de Duchess France, ex-organistratice du LyonJUG, et co-fondatrice de la conférence Mix-IT à Lyon.

Cyril Lacote est dévelopeur Java. Après 10 ans de prestations en SSII, voulant travailler à l’étranger avec Agnès, il a cru trouver un job de rêve chez Google à Londres. Contre toute attente, il n’y resta qu’un mois, avant de s’enfuir (on en reparlera).

Il participe aussi à l’organisation de la conférence Mix-IT (dont il portait ce jour un t-shirt, en complète indécence et irrespect pour Codeurs en Seine qui les recevait).

Agnès et Cyril se lancent alors dans un jeu de question-réponses pour sortir le public de leur léthargie (et surtout se déstresser un peu en cachette). L’audience est-elle heureuse, dans leur vie personnelle (mais on s’en fout complètement) ou dans leur job ?

Il s’avéra que oui, l’audience était plutôt heureuse.

En 2011, Agnès et Cyril sortaient ainsi d’une dizaine d’années de développement. Même un job dans une boîte de rêve comme Google ne fut pas l’idéal. Alors libres de toute contrainte et attache, ils ont décidé de partir faire un Tour du Monde, pour voir comment c’était ailleurs.

Pourquoi attendre 5 ans pour en parler ? Parce qu’entre temps ils ont essayé de survivre à la naissance de deux enfants rapprochés (et ce n’est pas une mince affaire). Et maintenant, ils ont le recul pour constater combien cela les a marqué, quelles leçons ils en ont tirées, et lesquelles ont été fructueuses.

Est-ce que vous reconnaissez ce minuscule pays de l’Afrique de l’Ouest ? Non, ce n’est pas le Bénin, mais son voisin le Togo.

Togo, Malaisie, Indonésie, USA, Suède. Voici les pays que traversera cette présentation. Dans leur tour du monde, ils sont aussi passés en Thaïlande, à Bali, en Australie, et en Nouvelle-Zélande, mais comme ils n’ont fait que profiter du pays, ils n’en parleront pas (même si ça vaut le coup).

Ils n’avaient pas envie de voyager qu’en touristes. Ils voulaient rencontrer des gens, et notamment des dévelopeurs. Alors ils ont fait ce qu’ils savaient faire : enseigner du Java et partager leur expérience de développeur dans différents meetups. Ils étaient souvent nourris et logés en échange de leurs formations, ce qui leur convenait parfaitement.

Agnès, alors très impliquée dans la communauté Duchess France, n’a pas pu s’empêcher de faire aussi un peu de prosélytisme, en aidant au montage de deux antennes locales : Duchess Africa et Duchess Indonésia.

Quelques faits marquants glanés autour du monde

Nous voilà partis pour un Tour du Monde en 15 minutes (record battu), où l’audience sera emportée dans un maelström d’anecdotes exotiques, tout à la fois savoureuses et pertinentes (espérons-le).

Direction Lomé, la capitale du Togo en Afrique de l’Ouest.

À Lomé, ils ont fait la rencontre d’Horacio, alors leader du TogoJUG, et depuis devenu un ami. Il leur proposait de faire un talk un samedi matin, dans un campus universitaire éloigné de la capitale. C’était à deux heures de taxi, et cela coûtait une journée de salaire local pour venir. Ils pensaient n’y trouver que quelques personnes : une soixantaine firent le déplacement ! On leur racontait alors que ce n’était pas étonnant : JCertif, la grosse conférence Java d’Afrique Centrale (leur Devoxx), accueillait des centaines de personnes faisant jusqu’à 3 jour de voyage pour y assister. Et traversaient parfois à pied l’imposant fleuve baignant le palais des congrès pour ne pas rater de conférence ! Une motivation qu’on aurait bien du mal à retrouver en France.

En France, Agnès et Cyril s’occupaient alors du LyonJUG. S’ils avaient organisé une session un samedi matin à Villeurbanne (la ville d’à-côté), ils n’y auraient probablement vu que 5 personnes maximum.

Sur Lyon, les communautés techniques sont fédérées par LyonTechHub, qui publie un calendrier de tous les meetups. Il y a un meetup chaque jour de la semaine, voir plusieurs. S’il est formidable de constater ce foisonnement des communautés, certaines peinent parfois à trouver leur public. Alors réjouissons-nous de cette richesse, là où d’autres n’ont droit qu’à très peu d’animations.

Agnès et Cyril étaient accueillis par une entreprise au Togo, où ils devaient former au Java de nouveaux embauchés. Ni l’entreprise, ni les élèves, n’étaient togolais : ils étaient tous de la Côte d’Ivoire. Mais l’entreprise les avait exfiltrés pour fuir la guerre civile sanglante qui ravageait le pays après la dernière élection présidentielle (pro-Gbagbo vs pro-Ouattara). Et une vraie guerre civile, avec des individus tués juste parce qu’ils étaient un peu enveloppés, comme le président sortant, qu’ils devaient donc nécessairement soutenir.

Ces élèves se retrouvaient ainsi dans un pays étranger, certes en sécurité, mais avec leur famille restée au pays. Autant dire qu’ils n’étaient pas pleinement sereins et concentrés pour suivre leur formation, jetant régulièrement un œil sur l’actualité de leur pays d’origine et prenant régulièrement des nouvelles de leurs proches.

En France, la plus violente des dernières guerres civiles en date a vu l’affrontement des partisans de l’appellation chocolatine, opposés à l’appellation pain au chocolat (qui est évidemment la bonne).

Encore une fois, réjouissons-nous des conditions de paix et de sérénité dans lesquelles nous avons la chance de pouvoir apprendre et travailler.

Leur copain Horacio leur expliquait aussi que les entreprises IT togolaises et africaines en général ne faisaient confiance qu’aux consultants blancs, et n’écoutaient pas les suggestions de leurs employés locaux. Elles préfèrent ainsi payer 2000€ par jour l’intervention d’un européen, alors que le SMIC mensuel n’est que de 50€ au Togo.

Certains occidentaux n’hésitent donc pas à s’expatrier, jouissant d’un pouvoir d’achat absolument considérable, avec une immense résidence, et 12 domestiques, de la cuisinière au chauffeur. Voilà un bel exemple de néo-colonialisme.

Même les startups africaines recrutent des blancs comme faire-valoir pour que leur proposition commerciale soit simplement écoutée. Leur copain Horacio, qui cherchait alors à créer son entreprise, leur a même demandé de jouer ce rôle pour lui. Malgré l’inconfortable culpabilité de ne pas aider leur ami, ils ont préféré refuser de participer à ce système.

En France, nous ne pouvons pas trop faire les malins : dans de nombreuses grosses entreprises, seuls certains consultants référencés ont leur mot à dire sur la stratégie ou l’architecture applicative, et les équipes de développeurs internes sont ignorées sur ces sujets importants. Plus le costume est cher, plus la voix est importante.

Après Lomé au Togo, nous nous envolons pour Kuala Lumpur en Malaisie (c’est rigolo c’est apparemment à la même latitude, traçant une ligne parfaitement parallèle à l’équateur). Bon, en vrai, ce n’est pas commme ça que le voyage s’est déroulé : entre ces deux destinations, Agnès et Cyril ont profité d’un long moment de détente en Thaïlande. Mais faute d’anecdote liée au développeur, ils n’en parleront pas.

Donc, Kuala Lumpur. À l’époque, ils ne connaissaient absolument rien de cette ville (Mission Impossible III n’était pas encore sorti), et n’avaient aucune image en tête. Et ce nom de Kuala Lumpur leur évoquait un exotisme absolu, genre temple d’Indiana Jones avec des singes dans la jungle.

Il s’est avéré que ce n’était pas tout à fait le cas.

Kuala Lumpur s’est révélée être une copie asiatique (et musulmane) de Londres, où les temples sont des tours de verre au service des dieux de la finance et du commerce.

Donnant une session au MalaysiaJUG, ils ont pu observé la richesse de l’université, et les conditions exceptionnelles auxquelles avaient droit les étudiants.

Bien loin de celles qu’ils avaient connues en France…

Voici l’INSA de Lyon, école d’ingénieur au top de leur région. Comme toute université française : murs décrépis, bancs cassés et moyens dérisoires.

Autre anecdote plus personnelle : Agnès et Cyril viennent de faire entrer leur plus grand fils Marius, 3 ans, à l’école maternelle. Alors qu’ils pensaient que Marius faisait ses premiers pas sur le long chemin serein de la vie, ils découvrent qu’ils seront plus de trente enfants entassés par classe, avec des peintures écaillées, des morceaux de plafond qui tombent, et un sol amianté (conseil de la mairie : “s’il ne frottent pas trop leurs pieds c’est sans danger”). Voici les moyens assignés à l’éducation publique en France. C’est assez pathétique, et peu rassurant sur l’avenir de la République.

Plus petit trajet de notre histoire : direction Jakarta, en Indonésie. Un véritable enfer urbain (plus de 25 millions de personnes en 2012), pollué par un trafic routier cauchemardesque.

Dans cet enfer, Agnès et Cyril ont rencontré deux jeunes femmes, Nety et Mila. Elles n’avaient pas 20 ans et menaient de front leurs études universitaires, une création d’entreprise, et quatre heures de transport quotidiennes. Régulièrement, elles prenaient leur scooter pour sillonner l’île de Java, dans des road trips pédagogiques où elles initiaient des jeunes au code.

Impressionnantes de motivation et d’énergie.

En France, les étudiants de 20 ans semblent moins préoccupés par leur avenir. Et consacrent en général leur temps libre à d’autres loisirs moins constructifs. N’est-ce pas Agnès ? (elle écumait alors les bars et les concerts).

Voici les élèves à qui ils donnaient des cours à l’Université de Jakarta. Et si vous regardez bien cette photo, vous y observerez une autre surprenante caractéristique de l’IT en Indonésie : une parité homme/femme exemplaire. Sans connaître les statistiques exactes, c’est bien ce qu’Agnès et Cyril ont constaté partout où ils sont allés.

Alors qu’en France, vous avez dû faire le même constat : c’est plutôt la bromance.

Cyril fait de la prestation informatique depuis 15 ans, et a dû travailler avec 150 personnes. Et probablement que 139 étaient des mâles trentenaires, blancs et hétéro. En gros, la seule développeuse qu’il a rencontrée, il lui a fait deux enfants…
C’est un peu exagéré, mais les développeuses qu’il a croisées doivent se compter sur les doigts d’une main (coucou Pierrette, coucou Daphné).

On a donc dans l’IT français un sacré problème de diversité. Et encore, le terme de diversité est mal choisi. “Diversité” sonne comme un luxe facultatif qui apporterait une petite touche d’exotisme charmant à l’équipe. Non, c’est juste un put*in de problème de représentativité : l’IT n’est pas à l’image de la France.

Voilà maintenant qu’on s’envole pour San Francisco, Californie, USA, capitale de l’informatique mondiale, siège des Google, Twitter, Facebook, Uber et AirBnb.

Agnès et Cyril y ont rencontré quelques stars qu’ils interviewaient pour un podcast (depuis abandonné) :

  • Romain Guy, un googler d’origine lyonnaise, qui a codé l’essentiel de l’UI de vos téléphones Android 
  • Pamela Fox, ancienne developer advocate de Google, alors chez Coursera, qu’ils ont fait venir à Mix-IT 
  • Malte Ubl, depuis devenu le tech lead de AMP, la technologie de Google pour rendre instantané le rendu des pages web sur mobile.

Ces gens travaillent dans un cadre merveilleux, pour des sociétés financièrement généreuses, et impactent des milliards de personnes. Pourtant, tout n’est pas idéal. C’était l’époque où les navettes Google (qui transportent leurs employés de San Francisco au siège de Mountain View à une heure de route) commençaient à se faire caillasser par la population qui leur reprochait la terrible gentrification de la ville.

Même avec une très bonne rémunération, Romain Guy a eu du mal à trouver une maison dans la Silicon Valley pour loger sa famille agrandie, il lui a fallu trois ans : quand une annonce paraît, des chinois débarquent dans l’heure qui suit avec des valises de liquide, contenant 500.000$ de plus que l’exorbitant prix demandé, et achètent sans visiter…

À Saint-Etienne, il n’y a peut-être pas Twitter ni Google, mais ça ne saurait tarder grâce à la French Tech. Non j’déconne. On n’est pas là pour troller sur la French Tech.

A Saint-Etienne, il n’y a peut-être pas Twitter ni Google, mais au moins l’immobilier n’est pas aussi tendu : moins de 1000€ le mètre carré. Quand Agnès et Cyril sont revenus de leur voyage sans aucune possession, et qu’ils prévoyaient la création de leur entreprise sans garantie de succès, et la procréation d’enfants dont ils ignoraient tout du coût de gestion, ils se sont alors installés à Saint-Etienne pour éviter d’ajouter la pression immobilière à leurs projets. L’aventure était alors financièrement plus sereine.

Direction Stockholm, en Suède. Ce n’était pas vraiment dans le cadre de leur tour du Monde, mais ils y sont allés récemment (en repérage pour peut-être s’y installer avec leurs enfants).

À Stockholm, Agnès et Cyril ont croisé un expatrié français depuis 8 ans (il travaille depuis chez Spotify, la boîte cool du coin). Il avait débarqué en Suède avec un enfant en très bas âge. Lors de son premier jour de travail, son manager passe près de son bureau à 17H, et lui demande ce qu’il est en train de faire.

— Et bien je travaille.
— Je croyais que tu avais un bébé à la maison.
— Heu oui, c’est ça.
— Et bien tu ne devrais pas être là. Rentre vite t’en occuper.

En Suède, on ne rigole pas avec la parité. Le partage des tâches domestiques et familiales n’est pas seulement conseillé, c’est surtout très mal vu que le père ne s’occupe pas suffisamment de ses enfants. Au point de se faire engueuler par son manager si un jeune papa reste après 17H au travail.

En France, et dans la plupart des pays occidentaux semble-t-il, ce n’est pas vraiment cet esprit.

Ce dessin (qui a été piqué à un inconnu sur Internet) représente assez bien l’état d’esprit traditionnel :

  • Tu peux avoir de l’argent et du temps libre, mais il ne faut pas avoir d’enfant, ou ne pas s’en occuper.
  • Tu peux avoir de l’argent et des enfants, mais tu n’auras alors pas de temps libre.
  • Tu peux avoir du temps et des enfants, mais tu n’auras probablement pas trop d’argent, avec un temps partiel.

OK, et après ?

Montrons combien les présentateurs ont fait preuve d’une clairvoyance éclairée pour forger leur destin.

S’ils avaient flippé de partir en long voyage sans salaire, Agnès et Cyril ont finalement réalisé que c’était très facile sans enfants. Alors, profitez-en tant qu’il est encore temps pour vous !

Le tour du Monde terminé, la question était maintenant de savoir quelles leçons ils allaient en tirer pour leur retour à la réalité professionnelle.

Agnès et Cyril ne voulaient plus être salariés, et encore moins en SSII, où on leur expliquait que le développement était une tâche à faible valeur ajoutée, et qu’il fallait penser à faire un vrai métier rentable : remplir des chiffres dans des cases Excel. :’(

Une des premières phrases du droit du travail indique qu’il s’applique uniquement s’il y a un rapport de subordination entre l’employé et l’employeur. Ainsi, le travail, après lequel court toute la société depuis des décennies (pour réduire le chômage et retrouver le plein-emploi), est fondamentalement une relation de subordination. Un employeur fera du chantage à l’employé : tu n’auras ton salaire que si tu fais cette tâche ingrate. Agnès et Cyril ne voulaient plus de cette subordination, et voulaient rester libres de choisir leur travail, et pour qui ils travaillaient.

Les entreprises libérées sont d’ailleurs à la mode. Mais aussi libérée que soit une entreprise, la relation de subordination fait qu’aucun salarié non actionnaire n’a un droit de regard sur le destin de l’entreprise. Un exemple récent est celui d’Octo. Si Agnès et Cyril ne connaissaient pas vraiment Octo, elle semblait une SSII plutôt cool, avec des employés pointus et reconnus. Mais du jour au lendemain, elle fut rachetée par Accenture. Reste à voir comment cela évoluera, mais il est fortement probabable que l’ambiance change du tout au tout, et que la stratégie d’Octo ne soit plus vraiment la même. Ainsi, ce n’est pas parce que tu adhères aux valeurs de ton entreprise que tu seras maître de son destin.

Agnès et Cyril ne veulent pas non plus dire que travailler dans une grosse société est forcément un échec. Mais eux-mêmes avaient du mal à imaginer des alternatives satisfaisantes. Alors ils veulent aussi présenter celle à laquelle ils sont arrivés.

Ils cherchaient donc une alternative au salariat. L’évidence est de se lancer en freelance. Mais cela ne leur convenait pas vraiment. Ils voulaient construire un projet collectif. Tout en sachant qu’ils n’étaient que des développeurs sans aucune autre compétence, perdus vers Saint-Etienne, et qu’ils ne voulaient ni locaux, ni managers, ni commerciaux.

Avec deux autres développeurs (bisous Cédric, bisous JB), ils se sont alors lancés dans une société coopérative : un homme = une voix, tous égaux, tous actionnaires. La transparence était aussi une valeur qui leur tenait à cœur. Malgré des écarts d’âge prononcés, ils ont décidé d’adopté un modèle de salaire encore plus simple que la fameuse grille de Buffer : tous le même salaire (2500€ net, et ils se partagent le reste à la fin de l’année, ce qui représenta quand même un bonus de 18 000€ nets pour chaque ninja l’année dernière). La grille de salaire de Ninja Squad est d’ailleurs aussi publique :)

Avec le recul, quatre ans après, est-ce que cela a fonctionné ?

Déjà, ils cherchaient une alternative au salariat. Le problème n’était pas tant le salariat que la relation de subordination induite. Ainsi, dans Ninja Squad, ils ont volontairement choisis d’être salariés, car leur statut de SAS le permettait, et ils voulaient par conviction participer au système social par répartition.

Au début, les commerciaux de leurs précédentes SSIIs ricanaient : “vous allez vous planter en beauté”.
Et certains leur prophétisaient une déconvenue : “avec un nom comme Ninja Squad, vous allez vraiment passer pour des guignols”. Avec le recul, bien qu’ils étaient loin de l’avoir calculé, le nom et l’esprit débridé assurent un excellent filtre. Si les grosses entreprises scélérosées (banque, assurance, grande distribution) ne veulent pas travailler avec ces guignols, c’est finalement tant mieux : ils ne veulent pas non plus travailler pour eux. Les quelques clients qui font la démarche de venir les voir sont déjà probablement des gens avec qui ils auront des affinités.

Le plus grand luxe d’avoir sa propre société c’est aussi de choisir ses clients, et refuser de travailler pour ceux dont on ne partage pas l’éthique. Après avoir éprouvé de l’empathie pour certains parcours de vie autour du monde, et après avoir fait des enfants, il y a certaines activités qu’on a encore moins envie d’encourager.

Quand on travaille en SSII, la SSII d’à côté est une concurrente, à qui il faut plutôt faire des croche-pieds que des bisous. Sans avoir d’explication formelle, il s’avère que dans leur petit monde des sociétés coopératives, l’entre-aide est plutôt de mise. En 2013, avec leurs amis de Scopyleft et de Lateral Thoughts, ils avaient animé un BoF à Devoxx sur les NoSSII (NoSSII : Not Only SSII). Depuis, ils se retrouvent sur un Slack. Et l’échange de tuyaux, de bons plans, et de missions, est toujours d’actualité.

Être libre dans sa société, c’est aussi maîtriser complètement son temps de travail, et définir l’équilibre avec la vie personnelle qui convient à chacun. Google est célèbre pour ses 20% de temps libre, et Ninja Squad fait vraiment pareil : ils ne facturent que 4 jours par semaine, et se gardent le vendredi pour travailler sur ce qu’ils veulent. Ce n’est pas toujours très sexy (il y a parfois de l’administratif, notamment la gestion des formations avec nos chers dinosaures du FAFIEC), mais au moins ont-ils du temps réservé pour cela.

Un autre avantage peut-être anecdotique d’avoir sa propre société est que cela résout un bête problème d’image. Quand vous avez votre entreprise, unipersonnelle ou non, il faut en assurer la promotion. Si les clients ne savent pas que vous existez, ils ne viendront pas vers vous. Ainsi, si vous êtes freelance, c’est en votre nom propre qu’il vous faut faire du marketing : “Oh la la qu’est-ce que je suis fort, j’ai encore fait ce projet, je parle encore à cette conférence”. Si vous avez une vraie société, avec son image, il suffit alors d’en dire tout le bien que vous voulez : votre humilité est sauve, vous ne parlez pas de vous. Vous avez transformé le personal branling en corporate branding !

Comment faire alors pour se lancer ? Est-ce compliqué ?

Et bien non ! Agnès, Cyril, et leurs collègues ninja Cédric et JB n’y connaissaient rien. Il leur a suffit de payer 1500€ un cabinet prestataire pour se faire interviewer sur la teneur des statuts qui leur convenaient, et assurer la création de la société.

La vraie difficulté, la plus importante, est de trouver les bonnes personnes qui feront les bons associés. Les gens qui resteront vos copains quand le sujet de l’argent arrivera sur la table. Il faut donc trouver les gens avec qui vous partagez vraiment les bonnes valeurs, et qui sont aussi vos complémentaires. Facile à dire, bien plus difficile à trouver.

Dans Ninja Squad, ils ont eu beaucoup de chance. Agnès et Cyril avaient rencontré Cédric dans l’associatif, et avaient travaillé avec lui dans ce cadre (LyonJUG, Mix-IT). Comme quoi, participer à la vie des communautés techniques est important ;). Ils avaient travaillé avec JB dans le cadre professionnel. Mais JB et Cédric ne se connaissaient pas. Ce dernier dit d’ailleurs : “ça n’avait aucun sens de monter une boîte avec un mec avec qui j’avais juste bu une bière en 5 minutes”. Mais ils ont finalement eu la chance incroyable d’être à la fois complémentaires et compatibles.

Un dernier point important avant de se lancer : trouver un bon comptable, parce vous allez passer beaucoup de temps avec lui. Alors mieux vaut trouver quelqu’un avec qui vous vous entendez bien, et qui vous mâchera le travail si la comptabilité n’est pas votre passion… Mais vous pourrez toujours changer par la suite.

Avec tout ça, dans le monde du développement où il y a tellement de travail insatisfait, il n’y a aucune raison que cela ne fonctionne pas, si vous travaillez correctement. Et avec peu de charges (pas de locaux, pas de commerciaux, pas de managers à payer), il est probable que vous viviez très bien.

Une conclusion subtile et inspirante

Voici, enfin, la conclusion, où apparaît soudainement, après un moment de flou, combien cette présentation est finalement bien construite et inspirante (normalement).

Donc, pour reboucler avec l’introduction, pourquoi est-on heureux ?

Agnès et Cyril sont tombés sur un TEDx de Jérome Bonaldi sur le bonheur. Il présentait différentes études statistiques qui ont permis de discriminer les facteurs influants sur le bonheur. Et le facteur le plus influent n’est pas celui qu’on pourrait croire.

Est-ce que les enfants et la famille contribuent au bonheur comme on le croit instinctivement ? Pas du tout !

On peut être parfaitement heureux ou malheureux avec ou sans enfant.

Est-ce que la religion aide ? Non plus !

Après, il y a les facteurs évidents, comme la santé. On sera évidemment plus heureux si on est en bonne santé.

Le cadre de vie joue aussi. On sera plus heureux dans un joli endroit qu’en vivant au bord d’une décharge.

Le niveau de vie contribue aussi : on sera évidemment plus heureux si on a les moyens de manger ce qui nous plaît, et de s’offrir quelques loisirs.

Mais enfin, le facteur le plus universel qui contribue le plus au bonheur est le sentiment d’avoir le contrôle de sa vie (empowerment, comme disent les américains).

Quelqu’un qui pense que sa vie est la faute du gouvernement ou de ce salaud de patron sera fondamentalement moins heureux que celui qui pense qu’il est maître de son destin. Il n’est même pas question de pouvoir vraiment, factuellement, changer sa vie, il est juste question de le penser !

Alors, vous qui êtes développeurs, dans ce monde où vous êtes tant recherchés, il est temps de prendre en main votre destin pour construire votre bonheur.

Les feedbacks

Un article suite à une interview paru dans le journal régional Paris-Normandie : Codeurs en Seine à Rouen : le métier de développeur web a de beaux jours devant lui.

Les tweets :


Cyril Lacôte


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Angular is moving fast, and we already have a minor release: 2.2! This contains the changes from Angular 2.1.x releases and Angular 2.2.0 various betas and RCs.

Upgrade

The most significant work has been done on the Ahead of Time compilation, and especially on the ngUpgrade support. That means you’ll be able to optimize your application going under migration. The router has received some love for those who want to migrate their ng1 apps to ng2: it’s now possible to use the Angular Router with the ngUpgrade!

Forms

One of the new features of this release is a modest contribution from me :) When you were using a template-driven form, the syntax was a bit painful to access some methods like hasError or getError:

<label>Username</label>
<input name="username" ngModel required #username="ngModel">
<div *ngIf="username.control.hasError('required')">Username is required</div>

Now with Angular 2.2+ we can directly access these methods on the local variable, without the need of accessing the control property:

<label>Username</label>
<input name="username" ngModel required #username="ngModel">
<div *ngIf="username.hasError('required')">Username is required</div>

Another feature introduced adds a ng-pending class on fields under pending async validations. In Angular, you can add validators on every field or group of fields. Such validators can be synchronous or asynchronous (for example asking the server if the chosen username is available). When an asynchronous validation is pending (the HTTP request is not completed yet for example), the ng-pending class is added to the field. You can use it to add some style or a spinner for example.

Router

The Router Module offers a very handy directive called RouterLinkActive, allowing us to add a specific class if a link is active. This directive is now exported, and can be used in our templates via a local variable:

<a routerLink="/races/1" routerLinkActive #route="routerLinkActive">
 Race 1 {{ route.isActive ? '(here)' : ''}}
</a>

That’s all for this small release. Check out our ebook and Pro Pack if you want to learn more about Angular!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Writing a technical book is a long, painful and difficult experience. I only took a small part in the writing of our two Angular books, Cédric being the main author, but even then, I know how hard it is.

It would be even harder if we had not chosen the good tools and processes to write it. And even more importantly, for you beloved readers (or future readers, hopefully), the book wouldn’t have such a good quality.

This post will give you an overview of the tools and processes we use. You’ll see that writing a book is very similar to writing software.

Team work

First of all, even if Cédric is, by large, the main developer of this book (I told you: a book is a software project), the book is actually the result of team work. The other ninjas, and even some friends external to Ninja Squad, helped translating and proof-reading the book. Or rather, the many iterations of the book.

You might think the book is written from the beginning to the end, chapter by chapter. That’s not how it works. The structure has changed several times. Some chapters have been rewritten almost completely, several times. Sometimes because we were not satisfied, sometimes because Angular itself made big changes to their architecture and APIs (the forms, router and testing modules come to mind).

It would have been a nightmare to achieve that with a giant shared Word document. So the main tools we used were a text editor, Github, Asciidoctor, and shell scripts.

Each chapter (in French and English), has its own asciidoc file in the project, which is hosted in a Github repo.

Each time someone makes a change, he/she creates a branch and a pull request, and the change is proof-read, commented and amended until we’re satisfied.

Using Asciidoctor makes that very easy: the document is pure readable text, which makes it simple to diff, comment and merge. Using the Asciidoctor toolchain, the asciidoc files are merged into a big document, and the HTML, PDF, epub and mobi versions of the book are generated.

Even the diagrams are generated from ascii-art, using asciidoctor-diagram. That makes it easy to produce and translate them.

We also use the comments from our Git commits, and a custom Java program, to generate a changelog.

Embedded code

Proof-reading the text is a human task. To proof-read the code snippets, however, we need more than that:

  • errors in the code are more difficult to spot;
  • we started working on the book when Angular was still in alpha, so each and every release introduced breaking changes in the code;
  • readers are forgiving when it comes to typos (and several ones were kind enough to provide feedback about them), but they would be frustrated if the provided code snippets were incorrect.

So what’s the solution here? Just as in any other software project: compilation, linting, and automated tests.

How can we compile and run automated tests for code snippets embedded in a document? Well, we can’t. So that’s not how we’re doing it.

Asciidoctor allows including sections of external files into an asciidoc document. Here’s how it looks like to extract a section of an external typescript.spec.ts in the asciidoc document:

:specs: ../tests/specs/typescript/typescript.spec.ts

[...]

[source, javascript, indent=0]
----
include::{specs}[tags=variable-with-types]
----

And here’s how it looks like in the typescript.spec.ts:

[...]

it('should introduce types', () => {
  // tag::variable-with-types[]
  let poneyNumber: number = 0;
  let poneyName: string = 'Rainbow Dash';
  // end::variable-with-types[]

  // asserts
  expect(poneyNumber).toBe(0);
  expect(poneyName).toBe('Rainbow Dash');
});

[...]

Many tests are much more complex than this one, obviously, but Angular is very much testable, including the HTML templates, so it really allows testing each and every code snippet in the book. Our big test suite even allowed finding and reporting bugs in Angular itself sometimes.

The pro pack

The pro pack is another similar story. We of course want to be able to evolve the exercises from one Angular version to the next, and to make sure our provided solution is correct. If you have tested our pro pack already (the first 6 exercises are free, in case you want to), you know that each exercise comes with

  • the project as it should be to start the exercise;
  • unit and end-to-end tests to check that your solution is correct;
  • tooling to check that all the code is covered by tests, and passes lint checks;
  • the solution of the exercise.

Once again, automation and tests are key things to make that correct and maintainable. So Cédric has created a build process using custom scripts. The process automatically executes all the checks for each exercise of the pro pack one by one, using the files of the provided solution. A bit as if a robot passed through all the exercises and wrote the solution.

The demo application, is simply the result of the final exercise of the pro pack, amended with some branding and additional goodies by a final step of this whole build process.

Regarding the backend API of ponyracer, it’s a Spring Boot application, written in Kotlin, and documented, once again using Asciidoctor and a set of automated tests using Spring REST Docs.

The training material

Of course, our training slides follow the same philosophy. Nothing is more frustrating than having a wrong snippet of code in your slides when you give a training. So we use an asciidoc file per training module to write our slides, thanks to asciidoctor-bespoke. This awesome project lets you write your slides in plain asciidoc and generates an HTML presentation (with Bespoke.js). A slide is really easy to write:

== Angular
[%build]
* announced in March 2014
* RC in May 2016
* stable in September 2016

As it is a pure HTML presentation, you can customize the CSS, and insert dynamic Angular demos right into it. Of course, all code samples are in external files and are unit-tested just as for the ebook.

So what?

This wasn’t meant to convince you to write a book by yourself. But even if you don’t, many of the tools and processes described in this post can be used in other contexts.

The next time your pointy haired boss asks you to write a big Word document to describe your architecture or your library, you might want to convince him that much better collaborative tools are available to software engineers.


JB Nizet


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Angular is moving fast, and we already have a minor release: 2.1!

If you haven’t heard, Angular is planning to have patch updates every week, minor releases every month, and major releases every 6 months.

That means Angular 3 should be Q1 or Q2 of 2017!

We plan to blog a little about each new release, to introduce you to the newest changes. We’ll ignore the tons of bug fixes, perf improvements and changes to ngUpgrade, to only focus on the new features.

This blog post contains the changes from Angular 2.0.x releases and Angular 2.1.0 various betas and RCs.

Router, modules, lazy-loading and pre-loading

The router comes with a really amazing feature allowing to lazy-load parts of your application. Instead of shipping a big bundle containing your whole application when your user lands on your home page, you can instead use this feature to only deliver the module he/she needs for this page, and then fetch the other modules only when required. Instead of paying the price of the load time once, you pay a smaller price, several times. And your initial load is faster!

But we can now do slightly better, with the 2.1.0 release. We can now define a strategy for pre-fetching the modules, even before the user needs them. Angular comes with a built-in strategy PreloadAllModules that will preload all modules as soon as possible. But you can also define your own strategy, to load only a few modules depending on your business logic (if the user is not an Administrator, maybe you can safely ignore the AdminModule for example).

Animations

Angular also comes with a great support for animations, with a custom DSL to define them. Angular 2.1.0 comes with two handy aliases :enter and :leave, to define animations that should run when the component is created or deleted.

@Component({
  animations: [
    trigger('myAnimation', [
      transition(':enter', [
        style({'opacity': 0}),
        animate('500ms', style({opacity: 1}))
      ])
    ])
  ]
})
export class AnimatedComponent {

With this animation, the component will slowly “fade in” as you can see on that plunker:

That’s all for this small release. Check out our ebook and Pro Pack if you want to learn more about Angular!


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Vous cherchez la version en Français ? C’est par ici.

To discover Angular, several thousands of you have read our ebook Become a ninja with Angular (thank you!). You may have noticed we spent a lot of time keeping it up to date with the tons of changes from the various betas and release candidates! All that for the price you decided, without DRM, in English and French, and with some ponies inside.

Thanks for all your feedbacks and amazing stories: it helps to know that this tremendous workload has been useful ;)

But we wanted to go further to share our experience in building modern JavaScript applications. An ebook is a great way to discover a topic, but it’s not enough to really master it. You have to experiment, test, read code and learn best practices. A great way is to follow a training, but we know that’s not always possible time-wise, location-wise, boss-wise or money-wise.

We came up with this idea to let you build a complete application step by step, an application that would be close to a real professional app (so… not a todo list…), but that would be fun enough (so… with ponies!). An application that would include components, services, routing, dependency injection, modules, http, websockets, lazy loading, authentication, forms, validations, performance tricks, production tricks, etc. And tests. Lots of tests. Because Angular makes it easy to have a great code coverage and to build robust applications. This application is Ponyracer (take a look)!

Purple pony

The Pro Pack lets you build Ponyracer, step by step, with more than 30 exercises, each dedicated to a specific topic. For each step:

  • we provide all the unit tests to validate 100% of your code
  • we provide you all the necessary resources
  • we provide you the instructions (in English or in French)
  • you have to complete the exercises (with the help of our ebook and resources)
  • you can submit your score with a tool we wrote (it analyzes your code, checks the quality, measures the completeness and submit the result to our platform)
  • you can check the ‘state of the art’ solution we wrote for each exercise
  • you can go to the next step and continue, or skip to whatever exercise you want, as we provide the full project ready to use for each step.

See the Pro Pack in action:

Pro Pack demo

You can check the Pro Pack platform at angular-exercises.ninja-squad.com and see the list of exercises by yourself.

We had nearly a hundred beta-testers over the past months, and they all have been ecstatic about it! As we regularly update the exercises (to keep up with the changes and new features in Angular) and add new ones, they often come back to see what changed, learn new tricks and how they can update their own projects.

The Pro Pack is really about gaining time and experience. It gives you an overview of everything you can do, how to test it and how to best implement it, in an always up-to-date fashion. If you complete the exercises, you will be able to tackle any project in Angular. I’m not saying that this will be an overnight process: you’ll have to spend several hours/days making your way through the Pro Pack. But we are really confident that what you’ll learn is way worth the money you’ll spend on the Pro Pack. The updates and new exercises will be free, of course.

Sounds interesting? It’s now available! Go buy it!

Oh and if you already bought the ebook, we have a nice discount for you! Just go to books.ninja-squad.com/discount to claim it! The offered discount will be slightly bigger than how much you gave, because we want to thank you for supporting us from the start.


Cédric Exbrayat


Ninja Squad books


Become a ninja with Angular
Cover of ebook Become a ninja with Angular

Pay what you want and support charity!


Devenez un Ninja avec AngularJS
Couverture du livre Devenez un Ninja avec AngularJS

Passez de débutant à ninja en AngularJS 1.4 avec un ebook à prix libre et pour une bonne cause !


Ninja Squad books



Formations

Angular

22-24 aout à Lyon
12-14 sept. à Paris
14-16 nov. à Lyon
12-14 dec. à Paris


Suivez-nous


Posts plus anciens