Skip to content

Commit

Permalink
chore(*): adding public folder Thu Feb 15 12:28:00 CET 2024
Browse files Browse the repository at this point in the history
0x-r4bbit committed Feb 15, 2024
0 parents commit 61b8022
Showing 1,330 changed files with 37,850 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions 2015-06-06-ng-messages-revisited/index.html

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 21790b11d643613a43a1039157bae9a3/git-detached-head-4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 2dd8e9b119adc196261798a139c683ab/injector-tree-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions 404.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions 404/index.html

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions 44820d092a70af998a5c33b718f3969d/cd-tree-7.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 477bd3a6ea642886f1669072185d43e3/transient-dependencies-4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 6f49d0871e4dd635846506901215239e/upgrade-2-phases-3.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 70c21bbe865416334d97588bb4da9a5a/git-branching-new-branch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 7ac7580fb5b9791eca7c265ce8f60ab6/git-detached-head-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 7cd38f19f51a597d970346585e57a9c6/injector-tree-3.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 8393e4d5673c51a3779a96651966d72d/cd-tree-10.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions 9f0fd18e6f0ea759062f1317f6f9d73f/git-detached-head-3.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blog.thoughtram.io
4 changes: 4 additions & 0 deletions a77dcff322d4e61495ce23c050433bf8/i18n-process.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
585 changes: 585 additions & 0 deletions all/index.html

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions angular/2015/03/21/angular-and-i18n-the-new-world.html

Large diffs are not rendered by default.

235 changes: 235 additions & 0 deletions angular/2015/03/27/building-a-zippy-component-in-angular-2.html

Large diffs are not rendered by default.

244 changes: 244 additions & 0 deletions angular/2015/04/09/developing-a-tabs-component-in-angular-2.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions angular/2015/05/09/writing-angular-2-code-in-es5.html

Large diffs are not rendered by default.

298 changes: 298 additions & 0 deletions angular/2015/05/18/dependency-injection-in-angular-2.html

Large diffs are not rendered by default.

214 changes: 214 additions & 0 deletions angular/2015/06/16/routing-in-angular-2.html

Large diffs are not rendered by default.

117 changes: 117 additions & 0 deletions angular/2015/06/25/styling-angular-2-components.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions angular/2015/06/29/shadow-dom-strategies-in-angular2.html

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions angular/2015/07/06/even-better-es5-code-for-angular-2.html

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions angular/2015/07/07/service-vs-factory-once-and-for-all.html

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions angular/2015/08/11/angular-2-template-syntax-demystified-part-1.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

211 changes: 211 additions & 0 deletions angular/2015/09/03/forward-references-in-angular-2.html

Large diffs are not rendered by default.

147 changes: 147 additions & 0 deletions angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

Large diffs are not rendered by default.

235 changes: 235 additions & 0 deletions angular/2015/10/24/upgrading-apps-to-angular-2-using-ngupgrade.html

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions angular/2015/11/16/multiple-transclusion-and-named-slots.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

177 changes: 177 additions & 0 deletions angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

151 changes: 151 additions & 0 deletions angular/2016/01/22/understanding-zones.html

Large diffs are not rendered by default.

141 changes: 141 additions & 0 deletions angular/2016/02/01/zones-in-angular-2.html

Large diffs are not rendered by default.

225 changes: 225 additions & 0 deletions angular/2016/02/22/angular-2-change-detection-explained.html

Large diffs are not rendered by default.

288 changes: 288 additions & 0 deletions angular/2016/03/14/custom-validators-in-angular-2.html

Large diffs are not rendered by default.

224 changes: 224 additions & 0 deletions angular/2016/03/21/template-driven-forms-in-angular-2.html

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions angular/2016/05/13/angular-2-providers-using-map-literals.html

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions angular/2016/05/16/exploring-rx-operators-map.html

Large diffs are not rendered by default.

175 changes: 175 additions & 0 deletions angular/2016/05/23/opaque-tokens-in-angular-2.html

Large diffs are not rendered by default.

292 changes: 292 additions & 0 deletions angular/2016/06/08/component-relative-paths-in-angular-2.html

Large diffs are not rendered by default.

239 changes: 239 additions & 0 deletions angular/2016/06/14/routing-in-angular-2-revisited.html

Large diffs are not rendered by default.

228 changes: 228 additions & 0 deletions angular/2016/06/16/cold-vs-hot-observables.html

Large diffs are not rendered by default.

207 changes: 207 additions & 0 deletions angular/2016/06/22/model-driven-forms-in-angular-2.html

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions angular/2016/07/18/guards-in-angular-2.html

Large diffs are not rendered by default.

493 changes: 493 additions & 0 deletions angular/2016/07/27/custom-form-controls-in-angular-2.html

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions angular/2016/09/14/bypassing-providers-in-angular-2.html

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions angular/2016/09/15/angular-2-final-is-out.html

Large diffs are not rendered by default.

247 changes: 247 additions & 0 deletions angular/2016/09/16/angular-2-animation-important-concepts.html

Large diffs are not rendered by default.

201 changes: 201 additions & 0 deletions angular/2016/10/10/resolving-route-data-in-angular-2.html

Large diffs are not rendered by default.

128 changes: 128 additions & 0 deletions angular/2016/10/13/two-way-data-binding-in-angular-2.html

Large diffs are not rendered by default.

279 changes: 279 additions & 0 deletions angular/2016/11/28/testing-services-with-http-in-angular-2.html

Large diffs are not rendered by default.

651 changes: 651 additions & 0 deletions angular/2016/12/27/angular-2-advance-testing-with-custom-matchers.html

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions angular/2017/01/09/a-revamped-angular-master-class.html

Large diffs are not rendered by default.

359 changes: 359 additions & 0 deletions angular/2017/02/02/making-your-angular-app-fast.html

Large diffs are not rendered by default.

166 changes: 166 additions & 0 deletions angular/2017/02/21/using-zones-in-angular-for-better-performance.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions angular/2017/05/08/angular-master-class-redux-and-ngrx.html

Large diffs are not rendered by default.

491 changes: 491 additions & 0 deletions angular/2017/05/23/custom-themes-with-angular-material.html

Large diffs are not rendered by default.

419 changes: 419 additions & 0 deletions angular/2017/07/26/a-web-animations-deep-dive-with-angular.html

Large diffs are not rendered by default.

276 changes: 276 additions & 0 deletions angular/2017/11/13/easy-dialogs-with-angular-material.html

Large diffs are not rendered by default.

380 changes: 380 additions & 0 deletions angular/2017/11/20/custom-overlays-with-angulars-cdk.html

Large diffs are not rendered by default.

330 changes: 330 additions & 0 deletions angular/2017/11/27/custom-overlays-with-angulars-cdk-part-two.html

Large diffs are not rendered by default.

706 changes: 706 additions & 0 deletions angular/2018/03/05/advanced-caching-with-rxjs.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions angular2/2015/11/23/multi-providers-in-angular-2.html

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions angularjs/2014/10/19/exploring-angular-1.3-ng-model-options.html

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions angularjs/2014/11/06/exploring-angular-1.3-angular-hint.html

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions angularjs/2014/11/19/exploring-angular-1.3-stateful-filters.html

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions angularjs/2014/12/18/exploring-angular-1.3-es6-style-promises.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

200 changes: 200 additions & 0 deletions angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

Large diffs are not rendered by default.

147 changes: 147 additions & 0 deletions angularjs/2015/01/11/exploring-angular-1.3-validators-pipeline.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions angularjs/2015/01/23/exploring-angular-1.3-ngMessages.html

Large diffs are not rendered by default.

204 changes: 204 additions & 0 deletions angularjs/2015/02/19/futuristic-routing-in-angular.html

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions angularjs/2015/02/21/around-the-globe.html

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions angularjs/2015/03/08/joining-betahaus-education.html

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html

Large diffs are not rendered by default.

148 changes: 148 additions & 0 deletions angularjs/es6/2015/01/23/exploring-angular-1.3-using-es6.html

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions annoucements/2015/06/17/anouncing-hanovers-second-rust-meetup.html

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions announcements/2014/06/06/we-are-thoughtram.html

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions announcements/2014/06/23/announcing-our-first-workshop.html

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions announcements/2014/07/04/tickets-are-on-sale-now.html

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions announcements/2014/07/05/git-ninya-class-comes-to-istanbul.html

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions announcements/2014/11/02/git-ninja-class-in-amsterdam.html

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions announcements/2015/04/19/upcoming-events-in-2015.html

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions announcements/2015/05/08/speaking-at-code-talks.html

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions announcements/2015/05/11/sponsoring-angularconnect.html

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions announcements/2015/08/31/going-full-time.html

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions announcements/2015/09/14/angular-training-day-bangkok.html

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions announcements/2015/10/08/pascal-becomes-a-gde.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions announcements/2015/11/19/how-we-run-trainings.html

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions announcements/2015/12/21/introducing-angular-2-master-class.html

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions announcements/2015/12/31/angular2-master-class-at-ng-nl.html

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions announcements/2016/02/10/sponsoring-angularconnect-again.html

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions announcements/2016/04/15/updates-and-announcements.html

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions announcements/2016/05/19/thomas-joins-thoughtram.html

Large diffs are not rendered by default.

131 changes: 131 additions & 0 deletions announcements/2016/06/23/updates-and-announcements.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions announcements/2017/02/09/dominic-joins-thoughtram.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions announcements/2019/09/02/more-GDE-power-at-thoughtram.html

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions announcements/2024/02/13/farewell.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions app-db11fdec89ef44788bcc.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app-db11fdec89ef44788bcc.js.map

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
---
layout: post
title: Angular Animations - Foundation Concepts
date: 2016-09-16T00:00:00.000Z
update_date: 2017-04-01T00:00:00.000Z
imageUrl: ../assets/images/banner/angular-2-component-animations.jpg
summary: >-
Animation in Angular is now easy and more intuitive... Learn foundational
animation concepts and start animating your Angular components!
categories:
- angular
tags:
- angular2
- animation
- components
- relative paths
topic: components
author: thomas_burleson
related_posts:
- Component-Relative Paths in Angular
- RxJS Master Class and courseware updates
- Advanced caching with RxJS
- Custom Overlays with Angular's CDK - Part 2
- Custom Overlays with Angular's CDK
- Easy Dialogs with Angular Material
related_videos:
- '175255006'
- '193524896'
- '189792758'
- '189785428'
- '175218351'
- '189618526'

---

Animations features often are scary goals for developers. And Angular's doctrine

> "... controllers should not directly modify DOM elements!"
made Animation features intimidating as hell. But **Angular animations are not scary!** Templates are closely associated/integrated with `@Component`. We will notice that animations following a similar pattern.

Let's build a component that hides and shows its contents, uses fade animation effects, and allows external components to easily trigger those fade effects.

### Our Scenario

Here is a simple Angular component with hide and show features. This sample, however, does not have animations (yet):

```js
@Component({
selector: 'my-fader',
template: `
<div *ngIf="visibility == 'shown'" >
<ng-content></ng-content>
Can you see me?
</div>
`
})
export class MyComponent implements OnChanges {
visibility = 'shown';

@Input() isVisible : boolean = true;

ngOnChanges() {
this.visibility = this.isVisible ? 'shown' : 'hidden';
}
}
```

This component simply publishes an `@Input() isVisible` property; which allows other external components to show/hide the text content... without any animations.

### Enable Animations Module

Since Angular 4.x, there's a new module `BrowserAnimationsModule` that introduces all animation capabilities. That's why we first have add that to our application module's `imports` like this:

```js
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
imports: [
...
BrowserAnimationsModule
]
...
})
export class AppModule {}
```

Once that is done, we can use any kind of animation API in our application. If we want to use animation function like `trigger()` or `state()`, we need to import them also from `'@angular/platform-browser/animations'` instead of `'@angular/core'`.

### Configure Component Animations

We want the `my-fader` component to **fade-in** or **fade-out** its text content. And we want to *animate* those fades effects.

To start animating, let's first add animation metadata to our component.

```js
@Component({
...,
template : ``,
animations: [
...
]
)]
class MyComponent() { ... }
```
Above we show that the `animations` metadata property is defined in the `@Component` decorator. Just like `template` metadata property!
Since our component has a `visibility` property whose state can change between `shown` and `hidden`, let’s configure animations to trigger and animate during each value change.
```js
animations: [
trigger('visibilityChanged', [
state('shown' , style({ opacity: 1 })),
state('hidden', style({ opacity: 0 }))
])
]
```
Before we add more metadata, let's talk about the syntax above. What does it mean... and why is this syntax used?
The techno-speak above is saying that when the `visibilityChanged` property changes and the value `== shown`, then the target element opacity changes to 1. And when the value changes to `== hidden`, the target element opacity should change to 0.
> Note: The `[@visibilityChanged]` binding is on `<div>` child content element in the `<my-fader>` component. It is NOT on the `<my-fader>` element itself. In other words, the animation target in our example is actually the `<div>` element; not the component **host** element.
Now, you might also wonder where `visibilityChanged` comes from? Because our component property is just called `visibility`. Hold your wild horses Mr. StageCoach, we'll clarify that soon!" Let's first talk about animation durations.
We want to animate these changes over a time duration instead of instantly hiding/showing the content. We need to configure a *transition* to specify animation durations. With Angular this is also suprisingly easy:
```js
animations: [
trigger(’visibilityChanged', [
state('shown' , style({ opacity: 1 })),
state('hidden', style({ opacity: 0 })),
transition('* => *', animate('.5s'))
])
]
```
With the above `transition`, we added information to the animation configuration so each trigger value change will have a 500 msec transition.
So a **fade-in** (opacity 0 -> 1, with a duration of 500 msec) will occur when the value changes from `hidden` to `shown`. And likewise the **fade-out** (opacity 1 -> 0, with a duration of 500 msec) will occur when the value changes from `shown` to `hidden`. By the way, you could also have used `animate('500ms')` to indicate the millsecond duration explicitly.
And what does the `transition('* => *', ...)` mean? Think of `* => *` as a transition from one state to another state; where `*` is a wildcard to mean **any** state value. If we wanted the *fade-out* to be slower than the *fade-in*, here is how we would configure the animation metadata:
```js
animations: [
trigger(’visibilityChanged', [
state('shown' , style({ opacity: 1 })),
state('hidden', style({ opacity: 0 })),
transition('shown => hidden', animate('600ms')),
transition('hidden => shown', animate('300ms')),
])
]
```
See how easy this is? This notation is so easy to understand.
### The Essential Concept
The essential take-away Animation concept is that **Angular Animations** are triggered on component <u>state changes</u>. And developers should consider <u>state changes</u> to be equivalent to <u>value changes in a property</u> of the component instance.
![super-cool](https://media.giphy.com/media/NUC0kwRfsL0uk/giphy.gif)
### Linking Animation to the Component
<br/>
While we configured the Animation metadata, I am sure you are wondering:
* How is the animation property `visibilityChanged` actually connected to the component?
* How are the animations linked to the component’s properties?
Since data-binding features are already supported between the **component** and its **template**, Angular uses a <u>special</u> template animation syntax to support triggering the animation after data-binding changes. So in the component template, we can do this:
```html
<div [@visibilityChanged]="visibility">
Can you see me? I should fade in or out...
</div>
```
Above the `@visibilityChanged` is the special template animation property and it uses databinding `[@visibilityChanged]=“visibility”` to bind the component's visibility property to the animation trigger property `visibilityChanged`.
Here is the entire component definition updated with Animation features:
```js
import { Component, OnChanges, Input } from '@angular/core';
import { trigger, state, animate, transition, style } from '@angular/platform-browser/animations';

@Component({
selector : 'my-fader',
animations: [
trigger('visibilityChanged', [
state('shown' , style({ opacity: 1 })),
state('hidden', style({ opacity: 0 })),
transition('* => *', animate('.5s'))
])
],
template: `
<div [@visibilityChanged]="visibility" >
<ng-content></ng-content>
<p>Can you see me? I should fade in or out...</p>
</div>
`
})
export class FaderComponent implements OnChanges {
@Input() isVisible : boolean = true;
visibility = 'shown';

ngOnChanges() {
this.visibility = this.isVisible ? 'shown' : 'hidden';
}
}
```
### Reducing Complexity
What if - instead of the using the extra `visibility` property - you just wanted to use the `isVisible` property directly? This would obviate `ngOnChanges()` and reduce the code complexity to:
```js
@Component({
animations: [
trigger('visibilityChanged', [
state('shown' , style({ opacity: 1 })),
state('hidden', style({ opacity: 0 })),
transition('* => *', animate('.5s'))
])
],
template: `
<div [@visibilityChanged]="isVisible" >
...
</div>
`
})
export class FaderComponent {
@Input() isVisible : boolean = true;
}
```
I love the tersity of this code. But this will not work without another **important** change to the animation metadata!
> Remember that the `@visibilityChanged` animation trigger property has defined states for the values: `shown` or `hidden`.
If you use the `myFader::isVisible` boolean property, then your animation state values must be changed to `true` and `false` since those are the possible values of the `isVisible` property.
```js
import { Component, OnChanges, Input } from '@angular/core';
import { trigger, state, animate, transition, style } form '@angular/platform-browser/animations';

@Component({
selector : 'my-fader',
animations: [
trigger('visibilityChanged', [
state('true' , style({ opacity: 1, transform: 'scale(1.0)' })),
state('false', style({ opacity: 0, transform: 'scale(0.0)' })),
transition('1 => 0', animate('300ms')),
transition('0 => 1', animate('900ms'))
])
],
template: `
<div [@visibilityChanged]="isVisible" >
<ng-content></ng-content>
<p>Can you see me? I should fade in or out...</p>
</div>
`
})
export class FaderComponent implements OnChanges {
@Input() isVisible : boolean = true;
}
```
> Extra Bonus: The demo has some extra features. The *host* `my-fader` element now has a purple background; when you hide the `my-fader` content children you will see the host background. This change was added so you can visually see the differences between the *host* and the *target* animation elements.
### Our Animation Workflow
Above we have an improved the component definition; enhanced with animation features. Here is a workflow of the [animation] process:
1. the input value for `isVisible` changes,
2. the template databinding updates the `@visibilityChanged` property,
3. the animation trigger is invoked,
4. the `@visibilityChanged` value is used to identify the **state** animations and transitions, and
5. the target element opacity (and other properties) change-animates for xxx msecs
### Animation Philosophy
One of the design goals for Angular Animations is to make it **easy** for developers to configure and use animations. The API and syntax is designed to be:
* intuitive
* declarative and
* immediately associated with the component using metadata
The best part of Angular Animation design is that the **component->template->animation** binding solution <u>decouples</u> the animation from the component internals and uses the template as the binding bridge.
The developer decides which component properties should bind to which animation triggers, then simply uses the possible component property values to set the animation *state* values accordingly.
> In most cases, you will never need to write JavaScript animation logic.
All the mechanics of preparing and managing the animations are hidden from the developer. This 'separation of concerns' provides HUGE benefits to allow developers to easily use Angular Animations with custom architectures & custom implementations.
### Animations with Components Hierarchies
Components should never be concerned with the details regarding animation of child components. Parent components can monitor and alter the public **state** of child components, but should never attempt to modify the internals of those components.
In our examples (above), parent components can simply change the state of the child `my-fader` instances and then magically the contents of the `my-fader` instance will fadeIn or fadeOut.
```js
@Component({
selector : 'my-app',
template: `
<my-fader [isVisible]="showFader">
Am I visible ?
</my-fader>
<button (click)="showFader = !showFader"> Toggle </button>
`
})
export class MyAppComponent {
showFader : boolean = true;
}
```
### Summary
The Angular Animation engine and compiler does all the hard work preparing, managing, and running the animations. Developers use the `@Component` metadata to declaratively define the component styles, templates, and [now] animations. And it is the component **template** that serves as the *bridge* to link the component instance state to the animation trigger property.
### Thanks
Kudos to [Matias Niemelä](https://twitter.com/yearofmoo) for the amazing Animation engine in Angular!
![matiasvikinghair](https://cloud.githubusercontent.com/assets/210413/18608523/49b8707c-7cb1-11e6-8d2c-ab43db07ca78.jpg)
These core animation features [discussed above] are available in the Angular 2.0.0 release. And never fear, Matias and his team are working hard on more amazing, intuitive Animation features. So stay tuned for even MORE cool features and blogs coming soon!
4 changes: 4 additions & 0 deletions b85647d61ad1b8e9ac1b77890f04b18a/injector-tree-4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions bac05e8fc17328a1f27f61b62254db8c/cd-tree-8.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions bca1a6fa015ccd5fca4e829987f67fa7/injector-tree.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions c0cf1789bd907b79e2b567861935a74d/a1-a2-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions categories/angular-2/index.html

Large diffs are not rendered by default.

317 changes: 317 additions & 0 deletions categories/angular/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/angularjs/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/annoucements/index.html

Large diffs are not rendered by default.

171 changes: 171 additions & 0 deletions categories/announcements/index.html

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions categories/company/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/es-6/index.html

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions categories/git/index.html

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions categories/machine-learning/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/meetups/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/rebase-book/index.html

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions categories/rust/index.html

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions categories/rx/index.html

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions categories/rxjs/index.html

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions categories/tools/index.html

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions cec743a8e1904a4f0268047a87341368/cd-4.svg

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions chunk-map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"app":["/app-db11fdec89ef44788bcc.js"],"component---src-templates-blog-post-js":["/component---src-templates-blog-post-js-6a14d6c49d22aa388ff9.js"],"component---src-templates-category-js":["/component---src-templates-category-js-4376524bed80ab31f5c7.js"],"component---src-pages-404-js":["/component---src-pages-404-js-6a74e57e5569370f5224.js"],"component---src-pages-all-js":["/component---src-pages-all-js-7aa251af6b402c5bb6a7.js"],"component---src-pages-confirmation-thank-you-js":["/component---src-pages-confirmation-thank-you-js-e20b16d362e2acd832ef.js"],"component---src-pages-finish-newsletter-subscription-js":["/component---src-pages-finish-newsletter-subscription-js-9bc9dd352c7e25398f2b.js"],"component---src-pages-index-js":["/component---src-pages-index-js-34313bc70d6e2470e416.js"]}
2 changes: 2 additions & 0 deletions commons-9a6c7e4a80f98fe6d0b9.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions commons-9a6c7e4a80f98fe6d0b9.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions commons.743a077edf8bbf03e9ea.css

Large diffs are not rendered by default.

227 changes: 227 additions & 0 deletions company/2017/08/17/company-offsite-2017.html

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions component---src-pages-404-js-6a74e57e5569370f5224.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions component---src-pages-404-js-6a74e57e5569370f5224.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions component---src-pages-all-js-7aa251af6b402c5bb6a7.js
1 change: 1 addition & 0 deletions component---src-pages-all-js-7aa251af6b402c5bb6a7.js.map
2 changes: 2 additions & 0 deletions component---src-pages-index-js-34313bc70d6e2470e416.js
1 change: 1 addition & 0 deletions component---src-pages-index-js-34313bc70d6e2470e416.js.map

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions component---src-templates-category-js-4376524bed80ab31f5c7.js
17 changes: 17 additions & 0 deletions confirmation-thank-you/index.html

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions d7da04ce5f28d8d8ef7000fa4ed625d9/cd-tree-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions fa57b8e3602b8eb222041a75460c72f9/di-in-angular2-5.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions fbff06a4dd044202d9f7ec4964db846f/cd-tree-12.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions fe6f7385644da0ec9e864f1f4a0a2594/git-detached-head-6.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions finish-newsletter-subscription/index.html

Large diffs are not rendered by default.

400 changes: 400 additions & 0 deletions git/2014/08/18/going-back-in-time-to-split-older-commits.html

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions git/2014/11/18/the-anatomy-of-a-git-commit.html

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions git/rebase-book/2015/02/10/understanding-branches-in-git.html

Large diffs are not rendered by default.

Binary file added icons/icon-144x144.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-384x384.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-48x48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-72x72.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-96x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions index.html

Large diffs are not rendered by default.

131 changes: 131 additions & 0 deletions iterators-in-rust/index.html

Large diffs are not rendered by default.

217 changes: 217 additions & 0 deletions lifetimes-in-rust/index.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions manifest.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"Articles by thoughtram","description":"High-quality, in-depth technical articles on Rust, Angular, Git and more by thoughtram.","short_name":"thoughtram blog","start_url":"/","background_color":"#ffffff","theme_color":"#384c54","display":"minimal-ui","icons":[{"src":"icons/icon-48x48.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"48x48","type":"image/png"},{"src":"icons/icon-72x72.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"72x72","type":"image/png"},{"src":"icons/icon-96x96.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"96x96","type":"image/png"},{"src":"icons/icon-144x144.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"144x144","type":"image/png"},{"src":"icons/icon-192x192.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"192x192","type":"image/png"},{"src":"icons/icon-256x256.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"256x256","type":"image/png"},{"src":"icons/icon-384x384.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"384x384","type":"image/png"},{"src":"icons/icon-512x512.png?v=50794189bf1d1bd3459211725d37e57e","sizes":"512x512","type":"image/png"}]}
191 changes: 191 additions & 0 deletions ownership-in-rust/index.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions page-data/2015-06-06-ng-messages-revisited/page-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-templates-blog-post-js","path":"/2015-06-06-ng-messages-revisited/","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram","authors":[{"id":"pascal_precht","name":"Pascal Precht","twitter":"PascalPrecht","img":"https://avatars2.githubusercontent.com/u/445106?s=460&v=4"},{"id":"christoph_burgdorf","name":"Christoph Burgdorf","twitter":"cburgdorf","img":"https://avatars0.githubusercontent.com/u/521109?s=460&v=4"},{"id":"dominic_elm","name":"Dominic Elm","twitter":"d3lm","img":"https://avatars0.githubusercontent.com/u/12571019?s=400&v=4"},{"id":"thomas_burleson","name":"Thomas Burleson","twitter":"thomasburleson","img":"https://avatars3.githubusercontent.com/u/210413?s=400&v=4"},{"id":"elvira_eulitz","name":"Elvira Eulitz","twitter":"ElviraEulitz","img":"https://avatars3.githubusercontent.com/u/29247040?s=400&v=4"},{"id":"maxim_koretskyi","name":"Maxim Koretskyi","twitter":"maxim_koretskyi","img":"https://avatars3.githubusercontent.com/u/6124091?s=400&v=4"}]}},"markdownRemark":{"id":"9992196a-6209-545e-bcf6-4dc2d7862dcf","excerpt":"If you’ve followed our series on Exploring Angular 1.3, you know that we’ve written an article about a new module that has been introduced then, called…","html":"<p>If you’ve followed our series on <a href=\"/exploring-angular-1.3\">Exploring Angular 1.3</a>, you know that we’ve written an <a href=\"/angularjs/2015/01/23/exploring-angular-1.3-ngMessages.html\">article</a> about a new module that has been introduced then, called ngMessages. If you haven’t read that article we highly recommend checking it out, since this article builds on top of that.</p>\n<p>Angular 1.4 has been released just a few days ago and weeks before that, there were several beta releases so we could make our feet wet with it. Next to a ton of improvements, bug fixes and features, this release also introduces a couple of minor breaking changes. In this article we discuss the latest changes to the ngMessages module, so you can update your application code accordingly.</p>\n<h2>ngMessagesInclude no longer an attribute</h2>\n<p>In applications where more than just a single form exists, we might want to reuse message templates. E.g. if we have an input field that is required, we want to display an error message that says so, in case the user forgets to enter anything. Such required fields appear very often in forms, so it would be quite cumbersome if we would have to define the same error message in a template over and over again.</p>\n<p>To solve that issue, there was an <code class=\"language-text\">ngMessagesInclude</code> attribute, which we could use in combination with the <code class=\"language-text\">ngMessages</code> directive, to include existing templates in other <code class=\"language-text\">ngMessages</code> container.</p>\n<p>To illustrate this scenario, here’s what such a template definition could look like:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>script/ng-template<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>required-message<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\n <span class=\"token operator\">&lt;</span>ng<span class=\"token operator\">-</span>message when<span class=\"token operator\">=</span><span class=\"token string\">\"required\"</span><span class=\"token operator\">></span>\n This field is required<span class=\"token operator\">!</span>\n <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>ng<span class=\"token operator\">-</span>message<span class=\"token operator\">></span>\n</span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>It’s an overloaded <code class=\"language-text\">script</code> tag that has an <code class=\"language-text\">id</code> attribute so we can refer to it later, and in that script we can just define a template. In order to (re)use that template, all we had to do, was to use the <code class=\"language-text\">ngMessagesInclude</code> attribute like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ng-messages</span> <span class=\"token attr-name\">ng-messages-include</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>required-message<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>otherForm.field.$error<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n ...\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ng-messages</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>What happens here, is that we just have our <code class=\"language-text\">ngMessages</code> container to display messages, but in addition to that, an existing template will be automatically included and activated. Included templates have always been added to the <strong>bottom</strong> of the <code class=\"language-text\">ngMessages</code> container.</p>\n<p><strong>In Angular 1.4, this has changed</strong>. <code class=\"language-text\">ngMessagesInclude</code> is no longer an attribute but a directive. Which means, if we want to use it the same way, instead of adding an attribute to the <code class=\"language-text\">ngMessages</code> container, we have to add the <code class=\"language-text\">ngMessagesInclude</code> directive as a child element to the container like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ng-messages</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>otherForm.field.$error<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">ng-message</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>minlength<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>...<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span>\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">ng-messages-include</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>required-message<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ng-messages</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Of course, this gives us much better control over what happens inside the <code class=\"language-text\">ngMessages</code> container. Don’t forget that the order of <code class=\"language-text\">ngMessage</code> directives inside a container configures the priority of each message.</p>\n<h2>Dynamic Message resolution</h2>\n<p>A better method to include existing message templates is already great, but the framework could do better. Even if <code class=\"language-text\">ngMessages</code> as a whole is a very nice and useful extension, it turns out that there was one issue with it, that should have been supported out of the box based on the nature of Angular.</p>\n<p>It was not possible to pass expressions to <code class=\"language-text\">ngMessage</code> directives, that evaluate to any kind of error type. This restricted us to only define static templates for each error message, which not only means we had to type more, it’s also not possible to render error messages dynamically that come from a server. In addition to that, it was not possible to use directives on ngMessages that do structure changes to the DOM (e.g. <code class=\"language-text\">ngIf</code>, <code class=\"language-text\">ngRepeat</code>).</p>\n<p><strong>Angular 1.4 fixes that issue</strong>. It introduces another directive called <code class=\"language-text\">ngMessageExp</code> which gets an expression that evaluates to an error type, so we can dynamically display messages. Combined with directives that do structural changes to the DOM, this can be very powerful. Just imagine you’d get a list of error messages back from a server due to asynchronous validation. With the new added features, this can easily be implemented like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ng-messages</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>otherForm.field.$error<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">ng-repeat</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>errorMessage in errorMessages<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">ng-message-exp</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>errorMessage.type<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n {{errorMessage.text}}\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ng-messages</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>We can simply iterate over a collection of messages using <code class=\"language-text\">ngRepeat</code> and dynamically display error messages based on the collection’s message objects. Super powerful.</p>","frontmatter":{"author":"pascal_precht","title":"ngMessages revisited","imageUrl":null,"date":"06 June 2015","summary":"With the release of Angular 1.4, a few changes landed that affect the ngMessages module. This article discusses what has changed.","categories":null}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/2015-06-06-ng-messages-revisited/","previous":{"fields":{"slug":"/angular/2015/05/18/dependency-injection-in-angular-2.html"},"frontmatter":{"date":"2015/05/18","title":"Dependency Injection in Angular","categories":["angular"]}},"next":{"fields":{"slug":"/angular/2015/06/16/routing-in-angular-2.html"},"frontmatter":{"date":"2015/06/16","title":"Routing in Angular","categories":["angular"]}}}}}
1 change: 1 addition & 0 deletions page-data/404.html/page-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-pages-404-js","path":"/404.html","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram"}}},"pageContext":{"isCreatedByStatefulCreatePages":true}}}
1 change: 1 addition & 0 deletions page-data/404/page-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-pages-404-js","path":"/404/","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram"}}},"pageContext":{"isCreatedByStatefulCreatePages":true}}}
1 change: 1 addition & 0 deletions page-data/all/page-data.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-templates-blog-post-js","path":"/angular/2015/06/25/taking-angular-master-class-to-the-next-level.html","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram","authors":[{"id":"pascal_precht","name":"Pascal Precht","twitter":"PascalPrecht","img":"https://avatars2.githubusercontent.com/u/445106?s=460&v=4"},{"id":"christoph_burgdorf","name":"Christoph Burgdorf","twitter":"cburgdorf","img":"https://avatars0.githubusercontent.com/u/521109?s=460&v=4"},{"id":"dominic_elm","name":"Dominic Elm","twitter":"d3lm","img":"https://avatars0.githubusercontent.com/u/12571019?s=400&v=4"},{"id":"thomas_burleson","name":"Thomas Burleson","twitter":"thomasburleson","img":"https://avatars3.githubusercontent.com/u/210413?s=400&v=4"},{"id":"elvira_eulitz","name":"Elvira Eulitz","twitter":"ElviraEulitz","img":"https://avatars3.githubusercontent.com/u/29247040?s=400&v=4"},{"id":"maxim_koretskyi","name":"Maxim Koretskyi","twitter":"maxim_koretskyi","img":"https://avatars3.githubusercontent.com/u/6124091?s=400&v=4"}]}},"markdownRemark":{"id":"4fe48dd9-040c-5129-b943-effc4aa4623f","excerpt":"We’ve been running our Angular Master Class since a couple of months now and travelled to many different countries and cities to meet you in person and exchange…","html":"<p>We’ve been running our <a href=\"http://thoughtram.io/angular-master-class.html\">Angular Master Class</a> since a couple of months now and travelled to many different countries and cities to meet you in person and exchange our experience. If you’ve attended one of our workshops, you know that we always ask for feedback so we can improve our material and of course, also your experience as an attendee.</p>\n<p>So far we always got very positive feedback. <strong>Our attendees are very happy and satisfied</strong> with our material, and also the way we run our workshops. Of course, this makes us very happy and we don’t want to stop here.</p>\n<p>In our workshops we try to give a very deep understanding of what happens under the hood, whether it is Angular or Git. Sometimes however, it happens that one or the other attendee would have liked to dig even deeper into certain topics, or learn about additional topics that are not covered in our Angular Master Class per se.</p>\n<h2>Angular Master Class extended</h2>\n<p>Guess what, we listened! Today we are very happy to announce that we’ve extended our material with additional and advanced topics.</p>\n<p><span\n class=\"gatsby-resp-image-wrapper\"\n style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px;\"\n >\n <a\n class=\"gatsby-resp-image-link\"\n href=\"/static/111defd88427efd35ea12cf8e9ff318f/b9380/angular-master-class-extended.png\"\n style=\"display: block\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n <span\n class=\"gatsby-resp-image-background-image\"\n style=\"padding-bottom: 52.751196172248804%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsSAAALEgHS3X78AAABXklEQVQoz2P4jwP8/ffv+/fv//ECBmTOv3//gCRQz90L507OnrqppW7b1Im3L57/+eMHEZr//gWS9y9fXOVlsy8p9Miald0Opn2u1g9v34TLEtD8/OGD9T52V+dPP7BkwZy8jCleDq9fvYS7i4Cz3754vqsw/fHBPdu7WhZ3ts1Ni//y6ROxmr9/+3pk1pR9GdGzzTT6gzw3TZv0989ffH7+CwP//oHUff706cKaZWuKc45tWPv92/d/IPAXrgxiB5BkwOoekCAYITvq58+fWGzesWPH6tWrV65cuWnTpuXLl69Zs+bChQsTJ05cu3bNZrDI1q1bL168uGr16i3bt+/cs/vU8eOfnz17eec2SPPdu3eBqletWrV79+5z586dOHHi1atX58+fP3ny5JkzZ06fPg1kv3v//syxY+vnzF7W27Nl1oxb+/a8vH2L4T8xABKQ79+9u3Pn9+cvcGEAxGRNSuWtG88AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n ></span>\n <img\n class=\"gatsby-resp-image-image\"\n alt=\"angular master class extended\"\n title=\"angular master class extended\"\n src=\"/static/111defd88427efd35ea12cf8e9ff318f/8ff1e/angular-master-class-extended.png\"\n srcset=\"/static/111defd88427efd35ea12cf8e9ff318f/9ec3c/angular-master-class-extended.png 200w,\n/static/111defd88427efd35ea12cf8e9ff318f/c7805/angular-master-class-extended.png 400w,\n/static/111defd88427efd35ea12cf8e9ff318f/8ff1e/angular-master-class-extended.png 800w,\n/static/111defd88427efd35ea12cf8e9ff318f/b9380/angular-master-class-extended.png 836w\"\n sizes=\"(max-width: 800px) 100vw, 800px\"\n loading=\"lazy\"\n />\n </a>\n </span></p>\n<p>Next to our existing material, we now offer enough slides and exercises for everything about Forms, the UI-Router and server communication. We also talk about <strong>migration</strong> and how you can prepare your applications for Angular 2.x today. You can find more information at our <a href=\"http://thoughtram.io/angular-master-class.html\">dedicated website</a>.</p>\n<p>And of course, that’s not enough. We’ve been frequently asked about a training on everything about testing your Angular applications. <strong>It’s on the way, so stay tuned!</strong></p>\n<p>You might wonder how this fits into our current schedule when running our workshop. At public events, the Angular Master Class is still a 2-day training. However, attendees can decide if they want to swap out topics to their needs so everyone gets the best experience possible.</p>\n<h2>What about in-house trainings?</h2>\n<p>Next to our public events we also do in-house trainings at companies that want to build their next application with Angular, or deepen their knowledge about the framework. With the extended material, <strong>companies have even more options to choose from</strong> when putting their package together.</p>\n<p>If your company has very specific needs, don’t hesitate to ask!</p>\n<h2>I want Angular 2.x!</h2>\n<p>We too! Since a lot of people ask us if we also do workshops on Angular 2.x, <strong>the answer is yes</strong>! Angular 2.x is not really around the corner, but actively developed so it can be shipped as soon as possible. We’re following the development every day, contribute to the framework and <a href=\"http://blog.thoughtram.io/categories/angular\">write</a> about isolated parts of it so you can already start learning. </p>\n<p>We also want to be able to offer you a very good training experience on Angular 2.x as soon as it is stable, that’s why we are already working on material. If this is interesting to you, make sure to follow us on <a href=\"http://twitter.com/thoughtram\">twitter</a> where we regularly post updates on our trainings.</p>","frontmatter":{"author":"pascal_precht","title":"Taking Angular Master Class to the next level","imageUrl":null,"date":"25 June 2015","summary":"We always collect feedback to make our material and trainings even better. We listened. Here's what we did.","categories":["angular"]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/angular/2015/06/25/taking-angular-master-class-to-the-next-level.html","previous":{"fields":{"slug":"/angular/2015/06/25/styling-angular-2-components.html"},"frontmatter":{"date":"2015/06/25","title":"Styling Angular components","categories":["angular"]}},"next":{"fields":{"slug":"/angular/2015/06/29/shadow-dom-strategies-in-angular2.html"},"frontmatter":{"date":"2015/06/29","title":"View Encapsulation in Angular","categories":["angular"]}}}}}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-templates-blog-post-js","path":"/angular/2015/12/10/ng-message-format-the-unheard-feature-in-angular.html","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram","authors":[{"id":"pascal_precht","name":"Pascal Precht","twitter":"PascalPrecht","img":"https://avatars2.githubusercontent.com/u/445106?s=460&v=4"},{"id":"christoph_burgdorf","name":"Christoph Burgdorf","twitter":"cburgdorf","img":"https://avatars0.githubusercontent.com/u/521109?s=460&v=4"},{"id":"dominic_elm","name":"Dominic Elm","twitter":"d3lm","img":"https://avatars0.githubusercontent.com/u/12571019?s=400&v=4"},{"id":"thomas_burleson","name":"Thomas Burleson","twitter":"thomasburleson","img":"https://avatars3.githubusercontent.com/u/210413?s=400&v=4"},{"id":"elvira_eulitz","name":"Elvira Eulitz","twitter":"ElviraEulitz","img":"https://avatars3.githubusercontent.com/u/29247040?s=400&v=4"},{"id":"maxim_koretskyi","name":"Maxim Koretskyi","twitter":"maxim_koretskyi","img":"https://avatars3.githubusercontent.com/u/6124091?s=400&v=4"}]}},"markdownRemark":{"id":"639e6c43-69dd-5f83-987e-aac13b7ee301","excerpt":"Angular 1.5 is pretty much around the corner and with a new release, new fixes, improvements and features are added to the framework. While this is awesome and…","html":"<p>Angular 1.5 is pretty much around the corner and with a new release, new fixes, improvements and features are added to the framework. While this is awesome and we’re all excited about it, it seems like we’re forgetting about all the nice things we already have.</p>\n<p><span\n class=\"gatsby-resp-image-wrapper\"\n style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 632px;\"\n >\n <a\n class=\"gatsby-resp-image-link\"\n href=\"/static/58ba3ccec1f6be120d9e129f954c49f7/f84ea/tweet.png\"\n style=\"display: block\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n <span\n class=\"gatsby-resp-image-background-image\"\n style=\"padding-bottom: 57.43670886075949%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAAB10lEQVQoz41T227bMAz1n+99T/uIAfuFrWiLtQ8ZsBYZ0iyO42tiJ7FTe07iuy3LpxSzBAU6bBNAkxIl8vCQ1kDrV1bgUJQYpIQk6fsewzAoF+u3wg40QmKXCYTHDkkh2Kc1ncDH6xE+3YxgmhbGkylmcwNt1+FvaxANHt0U77484/1tjA93MVpKoKmoD4aDsekiy3NEcYKc0CqUSuQFtbyc9bQfBomqEdjua0SHGknenRCqzybwEW7WiHbPcFwXlmVDJ5SrlQ/XW5I9hx+syeexzw8ChNEOge/Dtiw4jgPZC0bOAR3Pg24s6LGHMIxg2w6MxYIDbLchpj9nmFMCY2FyAm+5hGXbpFe/tc+8MkJVznqz4cwzXYdHDzYUxKS9SdlVgKZp0AnBmm3it+taLl/ZQohLAzngMcuQpHuSlKUoiUMJdD0u3f7XOt/TJBnx/khBKiK5RUJ2r3xNisN6SnT4iOOY/Blm0zFurj7D/PEd88d7RqeuylcjRQgHhGkOQfDLukWalaeMdYLj+ol4XCFJYup8hqfJGHe319BH95h8+0qlngK+nlFNPa7qmhFmRYGyKnkk5P9V+mboucvnIa6bAnm1Z7usav5zFPFC9Hx2nsmz/InfF+T0R6lfM2kOAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n ></span>\n <img\n class=\"gatsby-resp-image-image\"\n alt=\"tweet\"\n title=\"tweet\"\n src=\"/static/58ba3ccec1f6be120d9e129f954c49f7/f84ea/tweet.png\"\n srcset=\"/static/58ba3ccec1f6be120d9e129f954c49f7/9ec3c/tweet.png 200w,\n/static/58ba3ccec1f6be120d9e129f954c49f7/c7805/tweet.png 400w,\n/static/58ba3ccec1f6be120d9e129f954c49f7/f84ea/tweet.png 632w\"\n sizes=\"(max-width: 632px) 100vw, 632px\"\n loading=\"lazy\"\n />\n </a>\n </span></p>\n<p>A few days ago, we asked on twitter who’s interested to learn about an <strong>unheard feature</strong> in Angular. Based on the reactions to that tweet, it’s quite obvious that you all are and that’s awesome! So what is this unheard feature we’re talking about? If you read this article you can surely tell from its title that it’s probably about this thing called <strong>ngMessageFormat</strong>. We’ll get right into it but first we’d like to make one thing clear:</p>\n<p><strong>This feature is available since Angular 1.4</strong></p>\n<p>If you’re on version 1.4 or higher, this feature is already available to use. So, what you learn in the next couple of minutes you can use straight away!</p>\n<h2>Understanding Pluralization and Gender Selection</h2>\n<p>Earlier this year I gave a talk together with <a href=\"http://twitter.com/chirayuk\">Chirayu</a>, a former member of the Angular core team, about how the Angular project is going to solve internationalization and localization in the future. The talk can be watched <a href=\"https://www.youtube.com/watch?v=iBBkCA1M-mc\">right here</a> and if you’re more a reader kind of person, we wrote about everything in our article on <a href=\"/angular/2015/03/21/angular-and-i18n-the-new-world.html\">Angular and i18n - A new world</a>.</p>\n<p>One thing that is an essential part of i18n, but also a sort of isolated topic at the same time, is <strong>pluralization</strong> and <strong>gender selection</strong>. We probably all ran into this at a some point. For example, displaying a notification that says:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">You have {{numberOfMessages}} new messages.</code></pre></div>\n<p>While this works as long as <code class=\"language-text\">numberOfMessages</code> evaluates to something <code class=\"language-text\">&gt; 1</code>, it doesn’t fit anymore as soon as we have just a single message. Our template would look something like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">You have 1 new messages.</code></pre></div>\n<p>This can easily be solved with the <code class=\"language-text\">ngSwitch</code> directive, or, in fact Angular comes with an <code class=\"language-text\">ngPluralize</code> directive that introduces a couple more features (like <code class=\"language-text\">offset</code>) to make pluralization easy. Here’s an <code class=\"language-text\">ngPluralize</code> solution for the scenario above:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ng-pluralize</span> <span class=\"token attr-name\">count</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>numberOfMessages<span class=\"token punctuation\">\"</span></span>\n <span class=\"token attr-name\">when</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>{'1': 'You have one new message.',\n 'other': 'You have {} new messages.'}<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ng-pluralize</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Pluralization can be hard, especially if we consider that it can vary heavily depending on the language we’re using. While we have “one” and “more” in most of the european language rules, other languages have “one”, “few” and “more”.</p>\n<p>Another thing that comes into play is <strong>gender selection</strong>. Depending on a persons gender, we might need to output different text.</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">Send him an invite.\nSend her an invite.\nSend them an invite.</code></pre></div>\n<p>This can not be solved with <code class=\"language-text\">ngPluralize</code> today. Also, what if we have text in HTML attributes that needs to be pluralized as well?</p>\n<h2>Introducing ngMessageFormat</h2>\n<p>Luckily, there’s a standard called <a href=\"http://userguide.icu-project.org/formatparse/messages\">ICU Messageformat</a> which tackles pluralization and gender selection properly. In fact, with Messageformat, we can even nest gender selection rules and pluralization rules and vice-versa. But what has this to do with Angular?</p>\n<p>Well, as part of the effort for the new i18n solution, Angular’s interplation syntax got extended <strong>in Angular 1.4</strong>. In other words, we can basically overload the expression syntax with ICU Messageformat expressions. All we have to do is to include the <code class=\"language-text\">ngMessageFormat</code> module.</p>\n<p><code class=\"language-text\">ngMessageFormat</code> can be installed via npm using the following command:</p>\n<div class=\"gatsby-highlight\" data-language=\"sh\"><pre class=\"language-sh\"><code class=\"language-sh\">$ npm install angular-message-format</code></pre></div>\n<p>Once installed and included in our HTML document, we can add it as a module dependency and start using it right away! </p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">angular<span class=\"token punctuation\">.</span><span class=\"token function\">module</span><span class=\"token punctuation\">(</span><span class=\"token string\">'myApp'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'ngMessageFormat'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><strong>Pluralization with ngMessageFormat</strong></p>\n<p>With <code class=\"language-text\">ngMessageFormat</code> included, we can overload Angular expressions using a comma like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">{{EXPRESSION, TYPE,\n =VALUE { MESSAGE }\n ...\n}}</code></pre></div>\n<p>Whereas <code class=\"language-text\">EXPRESSION</code> is the expression that needs to be evaluated, <code class=\"language-text\">TYPE</code> specifies what we want to do <code class=\"language-text\">plural</code> or <code class=\"language-text\">select</code> for pluralization and gender selection respectively. Let’s use this syntax to output our notification, based on <code class=\"language-text\">numberOfMessages</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">{{numberOfMessages, plural,\n =0 { You have no new messages }\n =1 { You have one new message }\n other { You have # new messages }\n}}</code></pre></div>\n<p>As we can see, <code class=\"language-text\">#</code> can be used as a placeholder that gets replaced with the actual evaluated value. Another nice thing to notice: We can use still use Angular expressions and filters <strong>inside</strong> those messages!</p>\n<p><strong>Gender selection with ngMessageFormat</strong></p>\n<p>Gender selection uses the exact same syntax. All we have to do is to change the selection type and define messages for each gender:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\">{{genderExpression, select,\n male { Send him a message. }\n female { Send her a message. }\n other { Send them a message. }\n}}</code></pre></div>\n<h2>Conclusion</h2>\n<p>Unfortunately <a href=\"https://docs.angularjs.org/api/ngMessageFormat\">ngMessageFormat</a> is not very well documented and it didn’t get a lot of love after it has been released. However, it is right there and it wants to be used. Just remember that it allows you to pluralize not only HTML attributes, it even makes nesting of plural and gender selection possible!</p>","frontmatter":{"author":"pascal_precht","title":"ngMessageFormat - Angular's unheard feature","imageUrl":null,"date":"10 December 2015","summary":"Angular 1.5 is pretty much around the corner. It turns out that there's a feature that already landed in Angular 1.4, that no one really noticed. Curious?","categories":["angular"]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/angular/2015/12/10/ng-message-format-the-unheard-feature-in-angular.html","previous":{"fields":{"slug":"/angular2/2015/11/23/multi-providers-in-angular-2.html"},"frontmatter":{"date":"2015/11/23","title":"Multi Providers in Angular","categories":["angular2"]}},"next":{"fields":{"slug":"/announcements/2015/12/21/introducing-angular-2-master-class.html"},"frontmatter":{"date":"2015/12/21","title":"Angular 2 Master Class: Jump Start","categories":["announcements"]}}}}}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"componentChunkName":"component---src-templates-blog-post-js","path":"/angular/2016/05/13/angular-2-providers-using-map-literals.html","webpackCompilationHash":"0c5d630095500f933ccd","result":{"data":{"site":{"siteMetadata":{"title":"Articles by thoughtram","authors":[{"id":"pascal_precht","name":"Pascal Precht","twitter":"PascalPrecht","img":"https://avatars2.githubusercontent.com/u/445106?s=460&v=4"},{"id":"christoph_burgdorf","name":"Christoph Burgdorf","twitter":"cburgdorf","img":"https://avatars0.githubusercontent.com/u/521109?s=460&v=4"},{"id":"dominic_elm","name":"Dominic Elm","twitter":"d3lm","img":"https://avatars0.githubusercontent.com/u/12571019?s=400&v=4"},{"id":"thomas_burleson","name":"Thomas Burleson","twitter":"thomasburleson","img":"https://avatars3.githubusercontent.com/u/210413?s=400&v=4"},{"id":"elvira_eulitz","name":"Elvira Eulitz","twitter":"ElviraEulitz","img":"https://avatars3.githubusercontent.com/u/29247040?s=400&v=4"},{"id":"maxim_koretskyi","name":"Maxim Koretskyi","twitter":"maxim_koretskyi","img":"https://avatars3.githubusercontent.com/u/6124091?s=400&v=4"}]}},"markdownRemark":{"id":"ff877d01-684c-5d7f-a51f-a1b370e588c1","excerpt":"ng-conf happened just one week ago and there were many announcements about all things Angular. While this is good, sometimes these big announcements cause…","html":"<p>ng-conf happened just one week ago and there were many announcements about all things Angular. While this is good, sometimes these big announcements cause smaller features to remain unseen, because nobody really talks about them. That’s why we want to discuss providers using Map literals in this article, which is basically a new way of defining providers that landed just recently in the code base.</p>\n<h2>Provider recap</h2>\n<p>So what is it all about? Well, if you’ve read our articles on <a href=\"/angular/2015/05/18/dependency-injection-in-angular-2.html\">Dependency Injection in Angular</a>, you know that an injector needs something called a provider, that knows how to create an object of a certain type, or for a specific token.</p>\n<p>In other words, if we ask for a service dependency in one of our components like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Component <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> MyService <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./my-service.service'</span><span class=\"token punctuation\">;</span>\n\n@<span class=\"token function\">Component</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n selector<span class=\"token punctuation\">:</span> <span class=\"token string\">'my-component'</span><span class=\"token punctuation\">,</span>\n template<span class=\"token punctuation\">:</span> <span class=\"token string\">'{{myService.sayHello()}}'</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyComponent</span> <span class=\"token punctuation\">{</span>\n\n <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">private</span> myService<span class=\"token punctuation\">:</span> MyService</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We would run into an error, because even though, we import <code class=\"language-text\">MyService</code> and use that type to annotate our constructor parameter, there’s nothing that tells Angular (or the injector) what to do, when someone asks for something of that type. Of course, Angular could simply automagically call <code class=\"language-text\">new</code> on the given type and that’s it, but then there’s no way to replace the actual dependency with an object of a different type, or maybe even the way we want to construct a dependency (class vs. factory vs. value).</p>\n<p>That’s why Angular has the concept of providers, which basically act as a sort of recipe that describe how an object of a certain type is created.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Component <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> MyService <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./my-service.service'</span><span class=\"token punctuation\">;</span>\n@<span class=\"token function\">Component</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n selector<span class=\"token punctuation\">:</span> <span class=\"token string\">'my-component'</span><span class=\"token punctuation\">,</span>\n template<span class=\"token punctuation\">:</span> <span class=\"token string\">'{{myService.sayHello()}}'</span><span class=\"token punctuation\">,</span>\n providers<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>MyService<span class=\"token punctuation\">]</span> <span class=\"token comment\">// creates a provider for MyService</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyComponent</span> <span class=\"token punctuation\">{</span>\n\n <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">private</span> myService<span class=\"token punctuation\">:</span> MyService</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>You might know that adding a provider as shown above is actually a shorthand syntax for developer ergonomics. The same logic can be expressed with this more verbose syntax:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> provide <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core'</span><span class=\"token punctuation\">;</span>\n\n@<span class=\"token function\">Component</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n <span class=\"token operator\">...</span>\n providers<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n <span class=\"token function\">provide</span><span class=\"token punctuation\">(</span>MyService<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useClass<span class=\"token punctuation\">:</span> MyService <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyComponent</span> <span class=\"token punctuation\">{</span>\n <span class=\"token operator\">...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This enables us to create objects of different types, or even use completely different ways of constructing objects like using a factory function, or simply injecting a value.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">// creates instance of MyOtherService</span>\n<span class=\"token function\">provide</span><span class=\"token punctuation\">(</span>MyService<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useClass<span class=\"token punctuation\">:</span> MyOtherService <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// uses a factory function to create a dependency</span>\n<span class=\"token function\">provide</span><span class=\"token punctuation\">(</span>MyService<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token function-variable function\">useFactory</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span> foo<span class=\"token punctuation\">:</span> <span class=\"token string\">'bar'</span> <span class=\"token punctuation\">}</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// injects a simple value</span>\n<span class=\"token function\">provide</span><span class=\"token punctuation\">(</span>MyService<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useValue<span class=\"token punctuation\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>This is already pretty cool and powerful, because we can control what gets injected where in our application, without changing the application code itself.</p>\n<h2>Providers using Map Literals</h2>\n<p>As mentioned earlier, there’s a little change that makes the more verbose syntax a bit more ergonomic again. We can now define providers using Map literals. A Map literal, in TypeScript (or JavaScript) is really just an object hash. So instead of using the <code class=\"language-text\">provide()</code> function (which we need to import first), to create a provider, we can configure our providers using simple object structures.</p>\n<p>Here’s one of our earlier snippets, but this time we use Map literals:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">@<span class=\"token function\">Component</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n selector<span class=\"token punctuation\">:</span> <span class=\"token string\">'my-component'</span><span class=\"token punctuation\">,</span>\n template<span class=\"token punctuation\">:</span> <span class=\"token string\">'{{myService.sayHello()}}'</span><span class=\"token punctuation\">,</span>\n providers<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n <span class=\"token punctuation\">{</span> provide<span class=\"token punctuation\">:</span> MyService<span class=\"token punctuation\">,</span> useClass<span class=\"token punctuation\">:</span> MyOtherService <span class=\"token punctuation\">}</span>\n <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyComponent</span> <span class=\"token punctuation\">{</span>\n\n <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">private</span> myService<span class=\"token punctuation\">:</span> MyService</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Keep in mind that this is not a breaking change that has been introduced. It’s an additional syntax we can take advantage of. If you’re into saving key strokes, you might want to prefer Map literals over <code class=\"language-text\">provide()</code>.</p>","frontmatter":{"author":"pascal_precht","title":"Angular Providers using Map Literals","imageUrl":{"childImageSharp":{"sizes":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABQUlEQVQoz6WT21KDQBBE951bMBCIEn0WhYqy3EIkIP7/L43Ty0WgYqosH07tsjvpaXqICIqW7rML7dMLOW8V6c8J6aHsV4Uk4yW9CurWZwKCj+UnYXXfK7IHnJwbZDXdJWcyVg1Uw/B6IwFnT6eOHvKG7LggmwW8qiPv3JFbNEp0V7aqwVZ+qAb2sfzVsYDQgR2CHRdv4pxMRkfBgBFlCrV/zaYfa+xYY8fazLGwuNBPazrwK4+iaIII9nyOXH12hjPg8vN4D7BHHeKaBLExwdAdq8WYK6zZOqe/HzLcxOUkYi7ySKfw/4Kw5Rc5SU3B9BoNecgSmYU/+dxiMWUrynkQBQvkaiBWVJCpKNl1ribfn/eMz6gfo5iLCrjBh+3LWoXvSv58kpbmzjE0D3ccfDAMYRzY9nhaCo6fwH+Y/2u+AVbeQXzQKs7SAAAAAElFTkSuQmCC","aspectRatio":1.8603174603174604,"src":"/static/653020140e875db96c29b977cec7e8f3/b80d4/angular-2-providers-using-map-literals.png","srcSet":"/static/653020140e875db96c29b977cec7e8f3/d9446/angular-2-providers-using-map-literals.png 158w,\n/static/653020140e875db96c29b977cec7e8f3/2f6e7/angular-2-providers-using-map-literals.png 315w,\n/static/653020140e875db96c29b977cec7e8f3/b80d4/angular-2-providers-using-map-literals.png 586w","sizes":"(max-width: 586px) 100vw, 586px"}}},"date":"13 May 2016","summary":"Angular has a shorter syntax for creating providers. In this article we're going to take a look at how to create them using map literals.","categories":["angular"]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/angular/2016/05/13/angular-2-providers-using-map-literals.html","previous":{"fields":{"slug":"/announcements/2016/04/15/updates-and-announcements.html"},"frontmatter":{"date":"2016/04/15","title":"Updates and announcements","categories":["announcements"]}},"next":{"fields":{"slug":"/angular/2016/05/16/exploring-rx-operators-map.html"},"frontmatter":{"date":"2016/05/16","title":"Exploring Rx Operators: map","categories":["angular"]}}}}}
Loading

0 comments on commit 61b8022

Please sign in to comment.