Angular Dependency Injection Cheatsheet

Here’s is a cheatsheet on using Angular’s DI framework.

You can find it also in my Gist.


How to Inject Dependencies

When we want to use a dependent class/value, instead of creating them ourselves,
Angular’s DI framework will do it for us. In order to do this, we must define for the class/value a Token.
Once Angular sees that we want to inject the specific token, it will create the class/value and provide it to our class.

Injecting a Class

Create a class with Injectable decorator

1
2
3
4
5
6
import { Injectable } from '@angular/core';

@Injectable()
export class MyService {
...
}

Declare the class in a NgModule

1
2
3
4
5
NgModule ({
...
providers: [MyService],
...
})

Note: The above is a shortcut for

1
providers: [{ provide: MyService, useClass: MyService }]  // provide: <token>, useClass: <the class to instanciate>

Request injection

1
2
3
4
5
6
export class MyClientClass {

constructor (
private myService: MyService // Angular identifies the MyService token and provides an instance of the class.
){}
}

Injecting a Value

Declare the value in a NgModule

1
2
3
4
5
NgModule ({
...
providers: [{provide: 'API', useValue: 'https://api.example.com/v1.0'}],
...
})

Inject the value in a class

1
2
3
4
5
6
7
8
9
10
export myAPIClient {
constructor (
@Inject('API') apiHome: string
){}

//use the injected value
public getData(){
console.log(`Will fetch data from ${this.apiHome}`);
}
}

useFactory: Inject anything

You can inject a service that requires parameters in its constructor, or anything that can be returned from a function.

Injecting a parametrized service

Create your service as normal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Injectable } from '@angular/core';

@Injectable()
export class RandomProvider {

public modulo = 1;

constructor(modulo: number) { //Instanciating the class requires parameter
this.modulo = modulo
}

getRandomNumber(): number {
return this.modulo*Math.random();
}

}

Define Injection with useFactory

1
2
3
4
5
6
7
8
9
10
11
NgModule ({
...
providers: [
{
provide: RandomProvider,
useFactory(){
return new RandomProvider(4);
}
}]
...
})

Use the injection as normal

1
2
3
4
5
6
7
8
export class Randomizer {

constructor( private randomService: RandomService ) {}

public roll(): number {
return this.randomService.getRandomNumber();
}
}

Inject a constructed value

Let’s say that we want to inject an array of value that is constructed on start. We use useFactory to construct the value.

Construct the injectable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
NgModule ({
...
providers: [
{
provide: 'RANDOM_ARRAY',
useFactory(){
return [
Math.random(),
Math.random(),
Math.random()
];
}
}]
...
})

Inject the value as normal

1
2
3
4
5
6
7
8
export class ConsumeInjectedValue {

constructor( @Inject('RANDOM_ARRAY') private threeRandomValues: number[] ) {}

public consoleLog() {
console.log(this.threeRandomValues);
}
}

useFactory Dependencies

If the factory function itself has dependencies, they can be declared in the deps property.

1
2
3
4
5
6
7
8
9
10
11
12
13
import { HttpClientModule, HttpClient } from '@angular/core/http'

NgModule ({
...
providers: [{
provide: 'TRUE_RANDOM_SOURCE',
deps: [HttpClient], //here we declare dependencies of our factory
useFactory(httpClient: HttpClient) { // our factory needs an injectable (HttpClient)
return this.httpClient.get('http://api.example.com/randomval'); //fake URL - does not really work
}
}]
...
})

Angular Forms, Angular Directives

My Angular Tips-n-Tricks Gist got an update with notes on Directives and Angular Forms

You can find it here.

Here follow the changes:


Directives examples

NgForn

In this example we also demonstrate how to print an array of strings with a comma separator in between them.

in component

1
public values = ['one','two','three'];

in HTML template

1
2
3
4
<span *ngFor="let value of values; let i = index">
{{value}}
<span>{{i < (values.length-1) ? "," : ""}}</span>
</span>

NgSwitch

ngSwitchDefault is optional.

1
2
3
4
5
6
<div [ngSwitch] = "position">
<div *ngSwitchCase = "1">You are 1st!</div>
<div *ngSwitchCase = "2">You are 2nd!</div>
<div *ngSwitchCase = "3">You are 3rd!</div>
<div *ngSwitchDefault>You are not worth mentioning!</div>
</div>

NgStyle

Single property

1
<div [style.background-color]="'black'"></div>

Multiple properties at once

1
<div [ngStyle]="{color: 'white', 'background-color': 'blue'}"></div>

With units

1
2
3
<div [style.font-size.px]="13"></div>
<div [style.font-size.em]="1.5"></div>
<div [style.font-size.%]="45.5555"></div>

NgClass

1
2
<div [ngClass]="{bordered: true, 'white-background': false}"></div>
<div [ngClass]="['class1','class2','class3']"></div>

tip: You can use a classes object in your code and bind it to template

component code

1
public classesObj = { /* implement logic that build classes in the object*/ }; // e.g. {bordered: true; strongly: true}

HTML template

1
<div [ngClass]="classesObj"></div>

NgNonBindable

Helps you ‘disable’ bidding in HTML so you can use the

My Angular Tips-n-Tricks Gist got an update with notes on Directives and Angular Forms

You can find it here.

Here follow the changes:


Directives examples

NgForn

In this example we also demonstrate how to print an array of strings with a comma separator in between them.

in component

1
public values = ['one','two','three'];

in HTML template

1
2
3
4
<span *ngFor="let value of values; let i = index">
{{value}}
<span>{{i < (values.length-1) ? "," : ""}}</span>
</span>

NgSwitch

ngSwitchDefault is optional.

1
2
3
4
5
6
<div [ngSwitch] = "position">
<div *ngSwitchCase = "1">You are 1st!</div>
<div *ngSwitchCase = "2">You are 2nd!</div>
<div *ngSwitchCase = "3">You are 3rd!</div>
<div *ngSwitchDefault>You are not worth mentioning!</div>
</div>

NgStyle

Single property

1
<div [style.background-color]="'black'"></div>

Multiple properties at once

1
<div [ngStyle]="{color: 'white', 'background-color': 'blue'}"></div>

With units

1
2
3
<div [style.font-size.px]="13"></div>
<div [style.font-size.em]="1.5"></div>
<div [style.font-size.%]="45.5555"></div>

NgClass

1
2
<div [ngClass]="{bordered: true, 'white-background': false}"></div>
<div [ngClass]="['class1','class2','class3']"></div>

tip: You can use a classes object in your code and bind it to template

component code

1
public classesObj = { /* implement logic that build classes in the object*/ }; // e.g. {bordered: true; strongly: true}

HTML template

1
<div [ngClass]="classesObj"></div>

NgNonBindable

Helps you ‘disable’ bidding in HTML so you can use the {{ content }} double brackets as is.

1
2
3
<div ngNonBindable>
{{ this should be rendered as is and not interpolated. }}
</div>

Enums

Defining an Enum

1
2
3
4
5
6
7
8
// Simple Enum
enum Role = {Employee, Manager, Admin}

// Custom start value
enum RolesCustomStart = {Employee = 3, Manager, Admin}

// Custom values
enum RoleCustomValues = {Employee = 3, Manager = 5, Admin = 7}

Using Enum

1
const role = Role.Manager;

Finding Enum description by value

1
console.log ( Role[1]); // 'Manager'


Template Driven Forms

How to setup

import FormsModule

1
2
3
4
5
6
7
8
9
import { FormsModule } from '@angular/forms';

@NgModule ({
...
imports: [
FormsModule,
...
]
})

Add Form and submit handling
HTML Template:

1
2
3
4
5
<form #myForm="ngForm"
(submit)="handleSubmit(myForm.value)"
>
<button type="submit">Submit</button>
</form>

Component:

1
2
3
public handleSubmit(formValue: any) {
console.log(formValue);
}

Add Fields

1
2
3
4
5
6
7
8
9
<div>
<label for="usernameInput">Username</label>
<input type="text"
id="usernameInput"
name="username"
ngModel
placeholder="enter username"
>
</div>

Available form properties

  • myForm.errors
  • myForm.dirty
  • myForm.valid

Notes and Explanations

  • NgForm automatically binds to a <form> element and creates a FormGroup object called ngForm.
    With #myForm="ngForm" we actually grab this FormGroup object and bind it to a template variable.

  • NgForm automatically creates the (submit) event emitter.

  • NgModel directive creates automatically a FormControl named with the name value.

  • NgModel creates a one-way data bind (model -> view)


Reactive Forms

A quick reference guide on how to setup.

How to setup

import ReactiveFormsModule

1
2
3
4
5
6
7
8
import { ReactiveFormsModule } from '@angular/forms';
@NgModule ({
...
imports: [
ReactiveFormsModule,
...
]
})

define a FormGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
...

export FormComponent {

public userForm: FormGroup;
public

constructor(
private fb: FormBuilder
){
this.userForm = this.fb.group({
username: ['user1', Validators.required] //default value = 'user1', Optional validator = required
});

this.username = this.userForm.controls['username']; //optional. Allows easier reference in HTML template

}

public onSubmit(formValue: any) {
console.log('You submitted: ', formValue);
}


}

Create form and bind controls

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form [formGroup]="userForm"
(ngSubmit)="onSubmit(userForm.value)"
>

<label for="usernameElm">Username</label>
<input type="text"
id="usernameElm"
placeholder="enter username here"
[formControl]="userForm.controls['username']"
>

<!--
optionally you could bing the element to the Control property:
[formControl]="username"
-->

<button type="submit">Submit</button>

</form>

Handling errors and validation

Checking whole form validity example

1
2
<button [disabled]="!userForm.valid"
type="submit>Submit</button>

Detecting errors in controls

1
2
<input [class.error]="!userForm.controls['username'].valid"
...

Handling specific validation errors

1
2
3
<div *ngIf="userForm.controls['username'].hasError('required')">
You must enter a username
</div>

Good practice: see if control is touched

1
2
3
4
5
<!-- we are using the reference variable for leaner code -->

<input [class.error]="!username.valid && username.touched"

<div *ngIf="username.hasError('required') && username.touched"

Other validation options

Errors from FormGroup level

You can check for errors of specific field even in FormGroup level:

1
console.log (userForm.hasError('required','username');  // FormGroup.hasError(errorKey, fieldKey)

Custom Validators

Create a function that accepts FormControl object as parameter and returns an error string map {errorKey: boolean} if the error is valid.

Define Validator
Example: Not allow ‘admin’ as username.

1
2
3
4
5
private reservedUsernames (control: FormControl): { [string]: boolean } {
if (control.value === 'admin') {
return {reserved: true};
}
}

Apply Validator

1
2
3
4
5
this.userForm = this.fb.group({
username: ['', Validators.compose(
[Validators.required, this.reservedUsernames]
)]
});

Check in HTML template

1
2
3
<div *ngIf="userForm.controls['username'].hasError('reserved')">
Username reserved and cannot be used.
</div>

Monitor changes

There is an available Observable valueChanges in both FormGroup and FormControl classes.

1
2
3
4
5
6
7
this.userForm.valueChanges.subscribe(
(value: any) => console.log('Form Value changed to', value)
);

this.userForm.controls['usernames'].valueChanges.subscribe(
(value: string) => console.log('Current username: ', value);
);

2-way data bind

If you need to… you can bind an input control value to an external variable.

Component class:

1
2
3
4
5
6
public currentUsername: string;

//example of setting the value of currentUsername
public suggest() {
this.currentUsername = 'user'+Math.floor((Math.random() * 10) + 1);
}

HTML template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
<!-- ngModel binds the input element value to variable
<input type="text"
placeholder="enter username here"
id="usernameElem"
[formControl]="userForm.controls['username']"
[(ngModel)]="currentUsername"
>
...
<!-- the currentUsername reflects the value of input element -->
<div> Current Value: {{currentUser}}</div>

<!-- setting the currentUsername reflects the value back to input element -->
<button (click)="suggest()">Suggest a username</button>

Note: ngModel binds the input element value to variable. We still have to use [formControl] to bind the input element with the rest of our FormGroup and make it part of it (validation, etc).

Notes

  • When Angular sees [formGroup] in a <form> element, it does not automatically bind the ngForm FormGroup.

Captain out…

double brackets as is.

1
2
3
<div ngNonBindable>
{{ this should be rendered as is and not interpolated. }}
</div>

Enums

Defining an Enum

1
2
3
4
5
6
7
8
// Simple Enum
enum Role = {Employee, Manager, Admin}

// Custom start value
enum RolesCustomStart = {Employee = 3, Manager, Admin}

// Custom values
enum RoleCustomValues = {Employee = 3, Manager = 5, Admin = 7}

Using Enum

1
const role = Role.Manager;

Finding Enum description by value

1
console.log ( Role[1]); // 'Manager'


Template Driven Forms

How to setup

import FormsModule

1
2
3
4
5
6
7
8
9
import { FormsModule } from '@angular/forms';

@NgModule ({
...
imports: [
FormsModule,
...
]
})

Add Form and submit handling
HTML Template:

1
2
3
4
5
<form #myForm="ngForm"
(submit)="handleSubmit(myForm.value)"
>
<button type="submit">Submit</button>
</form>

Component:

1
2
3
public handleSubmit(formValue: any) {
console.log(formValue);
}

Add Fields

1
2
3
4
5
6
7
8
9
<div>
<label for="usernameInput">Username</label>
<input type="text"
id="usernameInput"
name="username"
ngModel
placeholder="enter username"
>
</div>

Available form properties

  • myForm.errors
  • myForm.dirty
  • myForm.valid

Notes and Explanations

  • NgForm automatically binds to a <form> element and creates a FormGroup object called ngForm.
    With #myForm="ngForm" we actually grab this FormGroup object and bind it to a template variable.

  • NgForm automatically creates the (submit) event emitter.

  • NgModel directive creates automatically a FormControl named with the name value.

  • NgModel creates a one-way data bind (model -> view)


Reactive Forms

A quick reference guide on how to setup.

How to setup

import ReactiveFormsModule

1
2
3
4
5
6
7
8
import { ReactiveFormsModule } from '@angular/forms';
@NgModule ({
...
imports: [
ReactiveFormsModule,
...
]
})

define a FormGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
...

export FormComponent {

public userForm: FormGroup;
public

constructor(
private fb: FormBuilder
){
this.userForm = this.fb.group({
username: ['user1', Validators.required] //default value = 'user1', Optional validator = required
});

this.username = this.userForm.controls['username']; //optional. Allows easier reference in HTML template

}

public onSubmit(formValue: any) {
console.log('You submitted: ', formValue);
}


}

Create form and bind controls

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form [formGroup]="userForm"
(ngSubmit)="onSubmit(userForm.value)"
>

<label for="usernameElm">Username</label>
<input type="text"
id="usernameElm"
placeholder="enter username here"
[formControl]="userForm.controls['username']"
>

<!--
optionally you could bing the element to the Control property:
[formControl]="username"
-->

<button type="submit">Submit</button>

</form>

Handling errors and validation

Checking whole form validity example

1
2
<button [disabled]="!userForm.valid"
type="submit>Submit</button>

Detecting errors in controls

1
2
<input [class.error]="!userForm.controls['username'].valid"
...

Handling specific validation errors

1
2
3
<div *ngIf="userForm.controls['username'].hasError('required')">
You must enter a username
</div>

Good practice: see if control is touched

1
2
3
4
5
<!-- we are using the reference variable for leaner code -->

<input [class.error]="!username.valid && username.touched"

<div *ngIf="username.hasError('required') && username.touched"

Other validation options

Errors from FormGroup level

You can check for errors of specific field even in FormGroup level:

1
console.log (userForm.hasError('required','username');  // FormGroup.hasError(errorKey, fieldKey)

Custom Validators

Create a function that accepts FormControl object as parameter and returns an error string map {errorKey: boolean} if the error is valid.

Define Validator
Example: Not allow ‘admin’ as username.

1
2
3
4
5
private reservedUsernames (control: FormControl): { [string]: boolean } {
if (control.value === 'admin') {
return {reserved: true};
}
}

Apply Validator

1
2
3
4
5
this.userForm = this.fb.group({
username: ['', Validators.compose(
[Validators.required, this.reservedUsernames]
)]
});

Check in HTML template

1
2
3
<div *ngIf="userForm.controls['username'].hasError('reserved')">
Username reserved and cannot be used.
</div>

Monitor changes

There is an available Observable valueChanges in both FormGroup and FormControl classes.

1
2
3
4
5
6
7
this.userForm.valueChanges.subscribe(
(value: any) => console.log('Form Value changed to', value)
);

this.userForm.controls['usernames'].valueChanges.subscribe(
(value: string) => console.log('Current username: ', value);
);

2-way data bind

If you need to… you can bind an input control value to an external variable.

Component class:

1
2
3
4
5
6
public currentUsername: string;

//example of setting the value of currentUsername
public suggest() {
this.currentUsername = 'user'+Math.floor((Math.random() * 10) + 1);
}

HTML template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
<!-- ngModel binds the input element value to variable
<input type="text"
placeholder="enter username here"
id="usernameElem"
[formControl]="userForm.controls['username']"
[(ngModel)]="currentUsername"
>
...
<!-- the currentUsername reflects the value of input element -->
<div> Current Value: {{currentUser}}</div>

<!-- setting the currentUsername reflects the value back to input element -->
<button (click)="suggest()">Suggest a username</button>

Note: ngModel binds the input element value to variable. We still have to use [formControl] to bind the input element with the rest of our FormGroup and make it part of it (validation, etc).

Notes

  • When Angular sees [formGroup] in a <form> element, it does not automatically bind the ngForm FormGroup.

Captain out…

Setup Bootstrap in Angular Project

Here follow instructions on how to setup Bootstrap in your Angular project.

The instructions below can be found in my Angular Gist.


The instructions here are based on this post…
https://medium.com/codingthesmartway-com-blog/using-bootstrap-with-angular-c83c3cee3f4a

The method here is using Bootstrap 4 (beta.2) with ng-bootstrap package.

Install ng-bootstrap

1
npm install --save @ng-bootstrap/ng-bootstrap

Install bootstrap 4

1
npm install --save bootstrap@4.0.0-beta-2

Add files to angular-cli.json

1
2
3
4
5
6
7
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
],

Import NgbModule
Import NgbModule in app.component

1
2
3
4
5
6
7
8
9
10
11
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

...

@NgModule({
declarations: [AppComponent, ...],
imports: [NgbModule.forRoot(), ...],
bootstrap: [AppComponent]
})
export class AppModule {
}

(Optionally) Import in other modules
If you need to import in other modules, import without the .forRoot() method:

1
2
3
4
5
6
@NgModule({
declarations: [OtherComponent, ...],
imports: [NgbModule, ...]
})
export class OtherModule {
}

Captain out

Angular tips n tricks Gist

Started a gist with Angular tips-n-tricks cheatseat, as I find them in my path. Sharing it with you.

Tips and Tricks can be found here:
Killerchip’s Angular notes Gist

Here’s the opening tips:

Simple input without complex forms

The following is a quick example of how to simply grab input from user, without using Angular forms and form builder.
Of course it is for very simple cases.

HTML Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<form>

<label for="firstName">First Name:</title>
<input name="firstName" #firstName> <!-- create a template variable that binds to input element -->

<br>

<label for="lastName">Last Name</title>
<input name="lastName" #lastName>

<button (click)="submitName(firstName,lastName)"> <!-- pass the input element to click event -->
Submit
</button>
</form>

In Component Class

1
2
3
4
5
submitName(firstName: HTMLInputElement, lastName: HTMLInputElement) {
// Then we can directly refer to elements as objects.
console.log(`Submiting: ${firstName.value} ${lastName.value}`);
return false; //returning false will stop event propagation, thus page does not reload.
}

Component adds class to itself

When defining a component you can define a class (and other attribute) on its own host element.

For example if you define the <my-component></my-component component, you can define it to have a class like <my-component class="my-component-class"> directly from compoent code. So you are not dependent on the “user” of this component to define the class.

This can be done with the @HostBinding

1
2
3
4
5
export class MyComponent {

@HostBinding('attr.class') cssClass='my-component-class'

}

Use a link as button

Sometimes is more ‘elegant’ to use an linke (href) as button instead of a button, even if we don’t want actually to navigate away from the page. But even with no URL in the href element the page ‘refreshes’. This is how to avoid this.

If the click-handler function returns false value, then this stops propagation of the click further.

HTML Template

1
<a href (click)="clickMe()">Click Me!</a>

Component code

1
2
3
4
public clickMe(): boolean {
console.log ('I will do something with the click');
return false; // returning false will stop click event from propagating
}

Captain Out…

ngx-translate-extract-csv v1.1.1

I’m happy to announce that v1.1.1 of ngx-translate-extract-csv is now out.

In this version you can define a custom separator for the CSV files.

See: https://github.com/killerchip/ngx-translate-extract-csv/blob/master/CHANGELOG.md

About ngx-translate-extract-csv

ngx-translate-extract-csv is a tool that becomes handy when doing Localization of Angular projects using ngx-translate library and the ngx-translate-extract tool. It will gather up the language .json files created into a single CSV file that can be easily imported to XLS.

Installation

1
npm install ngx-translate-extract-csv --save-dev

More info at:
https://www.npmjs.com/package/ngx-translate-extract-csv

Captain Out…

ngx-translate-extract-csv v1.0.0

I’m happy to announce that v1.0.0 of ngx-translate-extract-csv is now out.

ngx-translate-extract-csv is a tool that becomes handy when doing Localization of Angular projects using ngx-translate library and the ngx-translate-extract tool. It will gather up the language .json files created into a single CSV file that can be easily imported to XLS.

In v1.0.0 it now has the reverse operation. Split the “translated” CSV files into separate .json files to be used by the Angular app.

Installation

1
npm install ngx-translate-extract-csv --save-dev

More info at:
https://www.npmjs.com/package/ngx-translate-extract-csv

Captain Out…

Practice Building Android Layouts / Udacity course Lesson 4 notes

Sharing my draft notes from Udacity’s Android Basics - Lesson 4 online course

The course actually gave instructions and a challenge of building your own card as android app using Android Studio and deploying in a real Android device.

Here are my notes which can be found also at My GistHub:

Preparing to work with Android

From Design to Code

  1. Identify the Views to use (TextView? ImageView?)
  2. Position the Views (ViewGroups and positioning)
  3. Style the views (Fonts, colors, sizes, etc.)

Referencing an image

Images are saved in app/drawable folder. E.g androidparty.jpg.

Then they can be referenced as source from the ImageView.

1
2
3
<ImageView
...
android:src="@drawable/androidparty" />

Note: No need to add the extension of the image file.

A Sample ImageView

Use it as a quick reference for ImageView properties:

1
2
3
4
5
6
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/myImage"
/>

A Sample TextView

Use it as a quick reference for TextView properties:

1
2
3
4
5
6
7
8
9
10
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp"
android:text="Hello World"
android:fontFamily="sans-serif-light"
android:textColor="@android:color/white"
android:textSize="32sp"
/>

Draw Your Own Card challenge

Here’s the reference to my own card that I created as part of the practical challenge of this lesson:
https://discussions.udacity.com/t/make-your-own-card/19643/6766

I actually created a Memory card for my son Orestis to remember the trip we took with “Mountzouris” Locomotive train last summer (2017).

Captain Out…

Queries one after the other / RxJS examples

Another example use case of Angular-RxJS

You can find this example and other examples in my Gist Repository.

Launch a series of requests one after the other

In this example we launch a series of requests from information derived from an array. The requests are launched one after the other. This means a “next” request is launched only when the “previous” has been resolved.

The trick here is done by concatMap operator which does exactly what we want. So we create an Observable based on an array of initial values. Then concatMap will render them into a single stream the way we described above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/from';
import { concatMap } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

...

const myEvents: number[] = [1, 2, 3, 4, 5];
const myobs = Observable.from(myEvents).pipe(
concatMap (evt => {
return this.http.get(`https://jsonplaceholder.typicode.com/postss/${evt}`);
}),
)
.subscribe( /* handle events here */);

Bypass errors

The above approach, will stop the stream if one of the requests returns an error. What if we wanted to continue with the next requests even if one of them returned an error?

The materialize operator wraps all events (Events, Errors, Complete) to a new object called Notification. Thus errors and “complete” events are treated as normal events and do not stop the stream. Of course you have to handle the errors-complete events.

1
2
3
4
5
6
7
import { materialize } from 'rxjs/operators';

...
return this.http.get(`https://jsonplaceholder.typicode.com/postss/${evt}`).pipe(
materialize()
)
...

Voxxed Days Thessaloniki 2017 / Activity Overview and Take-aways

This is quick overview of the sessions that I participated and the key take-aways I take away from this conference.

Day 1

It’s a small world after all

Sander was very inspiring. The world is changing in blazing fast speed and software development ecosystem is trying to catch up with the demands.

My key take-aways:

  • Small movable parts in the software is the future (aka microservices, nanoservices).
  • Stop doing projects, and start buiding MVPs (minimum viable products).
  • Think small, deploy early and frequently.
  • Continuous Delivery: Pick backlog item, build it, test it, deploy it,… (Google does it with Gmail).
  • Testers: test less and less, build automated tests more and more.

Dealing with Information Overload - Personal Productivity for Techies

We are bombarded with information and we need to absorb it all… or not? Scott is a charismatic presenter and he gave advice on how to stay focused on your tasks, and be productive while not getting overwhelmed.

My key take-aways:

  • Effectiveness is different than efficiency. Effectiveness is doing the right things. Efficiency is doing things right.
  • Drop the ball. You don’t have to read everything. Triage your inbox.
  • Importance Vs Urgency:
  • FOMO = Fear of missing out. Don’t FOMO. If something is important it will come back to you several times.
  • Right 3 things that you wish to do each day, week, year. At the end of each day, week, year evaluate if you did it.
  • rescuetime.com: Productivity tool to understand where you spend your time.

I personally would recommend to take a look also at:

Mobile Web Performance

Estelle presented concerns and pitfalls when building web pages that will be (surely) accessed by mobile devices.

Find her presentation here:
https://estelle.github.io/viewsource/

Elegant Angular

Jeremy actually presented an overview of the Angular framework and its strong points, inlcuding Typescript, and RxJS (ReactiveX).

You can find his presentation here:
http://codefoster.com/deck/elegant-angular

Error Handling Made Easy

Stratos and his team is preparing a very promising Error Handling library, and I can’t wait for the Javascript version of it.

You can find the library for Swift and Java here:

Thinking Reactive in Javascript

Ivan introduced reactive programming and then mainly quick introduced React and Cycle.js.

SonarLint & SonarQube

Freddy introduced the tools SonarLint and SonarQube that perform static analysis on your code and can spot bugs, vulnerabilities, etc. Also presented the general method of how to write a static code analyzer.

Key take-away:
You install SonarLint / SonarQube and you find a long list of potential bugs, and poor quality. What do you do?… Answer: NOTHING!!! It works. If you start refactoring you inject more possibilities for bugs.

Start taking care of the quality of your new code as you write it. You will at some point will have to touch/re-write your existing code. It is at that point that you increase the quality of your existing code. In the long term, the precentage of low quality code will fade to zero.

The Secret Sauce of Successful Teams

Sven did a presentation on what are the characteristics of a successfull team, and the team practices they use at Atlassian.

It’s all summed up here:
Atlassian’s Team Playbook

Day 2

Javascript and the Rise of New Virtual Machine

Scott presented in his own unique way how the browser and Javascript are becoming the new platform that everything probably will be running on.

Serverless Computing & the rise of nanoservices

Paris explained and demonstrated how to get started with writing Azure functions. The future will be become more and more micro/nano-served.

AI and UX for Chatbots: A Practical Guide for Developers

Chatbots are on the rise and most probably will be the new mobile app. Dimitris and Stavros (the Chatbot ninjas) explained what a Chatbot is, how it is structured and how to approach them.

If you are interested in Chatbots look no further than their activities at Helvia.io.

Hardware Hacking for JavaScript Developers

Javascript is not only for the web. Javascript can help you create your own devices and gadgets. As Tim demonstrated by live-coding an Andruino and a Raspberry Pi 3 device, your imagation is the only limit.

Building an Angular.js app the “Angular” way : Lessons learned

Vasiliki and Alexandros explained to us how AngularJS framework helped to build a commercial app for their organization. Although if you get started today you will go for Angular.

Note: AngularJs = Angular v1, Angular = Angular v2+

Failed and successful stories with Technical Debt

Antonio started by explaining what is technical dept, and various success and failure stories dealing with it.

  • Technical Debt: he implied cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer.
  • What causes technical debt:
    • Business pressure to deliver.
    • Ignorance that we are creating it.
  • How to prevent it:
    • Code review
    • Say “No” when you have to. Don’t deliver poor quality due to pressure.
  • How to deal with it
    • Explain to business on “money” terms. Impact on customers and brand.
    • Make it a story, backlog items, etc.
    • Communicate with the team, communicate with the team and communicate with the team.

Closing

It was fun, it was exciting, it was usefull. Unfortunately I wish I could be in two places together to participate in all sessions.

Definately will participate next year.

Captain out…