RxJS Essentials. Part 7: Handling errors with the catch operator

In this article, I’ll show you aone of the RxJS operators for error handling – the catch() operator. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator
6. The switchMap operator

The Reactive Manifesto declares that a reactive app should be resilient, which means that the app should implement the procedure to keep it alive in case of a failure. An observable can emit an error by invoking the error() function on the observer, but when the error() method is invoked, the stream completes.

A subscription to an observable ends if one of the following occurs:

1. The consumer explicitely unsubscribes
2. The observable invokes the complete() method on the observer
3. The observable invokes the error() method on the observer

RxJS offers several operators to intercept and handle the error before it reaches the code in the error() method on the observer.

* catch(error) – intercepts the error and you can implement some business logic to handle it
* retry(n) – retries the erroneous operation up to n times

* retryWhen(fn) – retries the erroneous operation as per the provided function

In this article, I’ll show you an example of using the catch() operator. Inside the catch() operator you can check the error status and react accordingly. The following code snippet shows how to intercept an error, and if the error status is 500, switch to a different data producer to get the cached data. If the received error status is not 500, this code will return an empty observable and the stream of data will complete. In any case, the method error() on the observer won’t be invoked.

.catch(err => {  
    console.error("Got " + err.status + ": " + err.description);

    if (err.status === 500){
        console.error(">>> Retrieving cached data");

        return getCachedData();  // failover
    } else{
      return Rx.Observable.empty();  // don't handle the error
    }
})

The following listing shows the complete example, where we subscribe to the stream of beers from a primary source – getData() – which randomly generates an error with the status 500. The catch() operator intercepts this error and switches to an alternative source – getCachedData().

function getData(){
    var beers = [
        {name: "Sam Adams", country: "USA", price: 8.50},
        {name: "Bud Light", country: "USA", price: 6.50},
        {name: "Brooklyn Lager", country: "USA", price: 8.00},
        {name: "Sapporo", country: "Japan", price: 7.50}
    ];

    return Rx.Observable.create( observer => {
        let counter = 0;
        beers.forEach( beer => {
                observer.next(beer);   // 1
                counter++;

                if (counter > Math.random()*5) {   // 2
                    observer.error({
                            status: 500,
                            description: "Beer stream error" 
                        });
                } 
            }
        );

        observer.complete();}
    );
}

// Subscribing to data from the primary source
getData() 
    .catch(err => {  // 3
        console.error("Got " + err.status + ": " + err.description);
        if (err.status === 500){
            console.error(">>> Retrieving cached data");
            return getCachedData();   // 4
        } else{
          return Rx.Observable.empty();  // 5  
        }
    })
    .map(beer => beer.name + ", " + beer.country)
    .subscribe(
        beer => console.log("Subscriber got " + beer),
        err => console.error(err),
        () => console.log("The stream is over")
    );

function getCachedData(){  // 6
    var beers = [
        {name: "Leffe Blonde", country: "Belgium", price: 9.50},
        {name: "Miller Lite", country: "USA", price: 8.50},
        {name: "Corona", country: "Mexico", price: 8.00},
        {name: "Asahi", country: "Japan", price: 7.50}
    ];

    return Rx.Observable.create( observer => {
        beers.forEach( beer => {
                observer.next(beer);
            }
        );

        observer.complete();}
    );
}

1. Emit the next beer from the primary data source
2. Randomly generate the error with the status 500
3. Intercept the error before it reaches the observer
4. Failover to the alternative data source
5. Don’t handle the non-500 errors; return an empty observable to complete the stream
6. The alternative data source for failover

The output of this program can look as follows:

Subscriber got Sam Adams, USA
Subscriber got Bud Light, USA
Got 500: Beer stream error
>>> Retrieving cached data
Subscriber got Leffe Blonde, Belgium
Subscriber got Miller Lite, USA
Subscriber got Corona, Mexico
Subscriber got Asahi, Japan
The stream is over

NOTE: To see it in CodePen, follow this link. Stay tuned…

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

Advertisements

RxJS Essentials. Part 6: The switchMap operator

In this article I’ll introduce the switchMap() operator. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator

In the previous article of this series, I demoed the use of flatMap(). While flatMap() unwraps and merges all the values emitted by the outer observable, the switchMap() operator handles the values from the outer observable but cancels the inner subscription being processed if the outer observable emits a new value. The switchMap() operator is easier to explain with the help of its marble diagram shown next.

The outer observable emits the red circle, and switchMap() emits the item from the inner observable (red diamond and square) into the output stream. The red circle was processed without any interruptions because the green circle was emitted after the inner observable finished processing.

The situation is different with the green circle. The switchMap() managed to unwrap and emit the green diamond, but the blue circle arrived before the green square was processed. So the subscription to the green inner observable was cancelled, and the green square was never emitted into the output stream. In other words, the switchMap() operator switched from processing of the green inner observable to the blue one.

The following example has two observables. The outer observable uses the function interval() and emits a sequential number every second. With the help of the take() operator, we limit the emission to two values: 0 and 1. Each of these values is given to the switchMap() operator, and the inner observable emits three numbers with the interval of 400 milliseconds.

let outer$ = Rx.Observable
               .interval(1000)
               .take(2);

let combined$ = outer$.switchMap((x) => {  
     return Rx.Observable
	          .interval(400)
	          .take(3)
	          .map(y => `outer ${x}: inner ${y}`)
});

combined$.subscribe(result => console.log(`${result}`));

The output of this script is shown next:

outer 0: inner 0
outer 0: inner 1
outer 1: inner 0
outer 1: inner 1
outer 1: inner 2

Note that the first inner observable didn’t emit its third value 2. Here’s the timeline:

1. The outer observable emits zero and the inner emits zero 400 milliseconds later
2. In 800 milliseconds later, the inner observable emits 1
3. In 1000 milliseconds the outer observable emits 1, and inner observable was unsubscribed
4. The three inner emissions for the second outer value went uninterrupted because it didn’t emit any new values

If you replace flatMap() with switchMap() the inner observable will emit three values for each outer value as shown below.

outer 0: inner 0
outer 0: inner 1
outer 0: inner 2
outer 1: inner 0
outer 1: inner 1
outer 1: inner 2

NOTE: To see it in CodePen, follow this link.

The chances are slim that you’ll be writing outer and inner observables emitting integers but there are various practical use cases for switchMap(). For example, in my Angular apps (Angular comes with RxJS) I use switchMap() with the HttpClient object (it returns observable) to cancel pending HTTP requests. Just think of a user that types in an HTML input field (the outer observable) and the HTTP requests are being made (inner observable) on each keyup event. The circles on the diagram are the three characters that the user is typing. The inner observables are HTTP requests issued for each character. If the user entered the third character but the HTTP request for the second one is still pending, it’ll get cancelled.

TIP. The function interval() is handy if you want to invoke another function periodically based on the specified time interval. For example, myObservable.interval(1000).subscribe(n => doSometing()) will result in calling the function doSomething() every second.

NOTE: If your code has nested subscribe() calls, this should be a red flag to you. Consider re-writing this code using flatMap(), switchMap(), or concatMap().

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

In the next article, I’ll show how to intercept errors from an observable stream with the catch(operator.)

RxJS Essentials. Part 5: The flatMap operator

In this article I’ll introduce an RxJS flatMap() operator. Previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject

In some cases, you need to treat each item emitted by an observable as another observable. In other words, the outer observable emits the inner observables. Does it mean that we need to write nested subscribe() calls (one for the outer observable and another for the inner one)? No, we don’t. The flatMap() operator takes each item from the outer observable and auto-subscribes to it.

Some operators are not explained well in RxJS documentation, and we recommend you to refer to the general ReaciveX (reactive extensions) documentation for clarification. The flatMap() operator is better explained there, and it states that flatMap() is used to “transform the items emitted by an observable into observables, then flatten the emissions from those into a single observable”. This documentation includes the following marble diagram:

As you see, the flatMap() operator takes an emitted item from the outer observable (the circle) and unwraps its content (the inner observable of diamonds) into the flattened output observable stream. The flatMap() operator merges the emissions of the inner observables so their items may interleave.

The following code listing has an observable that emits drinks, but this time it emits not individual drinks, but palettes. The first palette has beers and the second – soft drinks. Each palette is observable. We want to turn these two palettes into an output observable with individual beverages.

function getDrinks() {

    let beers = Rx.Observable.from([   // 1
        {name: "Stella", country: "Belgium", price: 9.50},
        {name: "Sam Adams", country: "USA", price: 8.50},
        {name: "Bud Light", country: "USA", price: 6.50}
    ], Rx.Scheduler.async);

    let softDrinks = Rx.Observable.from([    // 2
        {name: "Coca Cola", country: "USA", price: 1.50},
        {name: "Fanta", country: "USA", price: 1.50},
        {name: "Lemonade", country: "France", price: 2.50}
    ], Rx.Scheduler.async);

    return Rx.Observable.create( observer => {
            observer.next(beers);     // 3
            observer.next(softDrinks);   // 4
            observer.complete();
        }
    );
}

// We want to "unload" each palette and print each drink info

getDrinks()
  .flatMap(drinks => drinks)    // 5   
  .subscribe(  // 6
      drink => console.log("Subscriber got " + drink.name + ": " + drink.price ),
      error => console.err(error),
      () => console.log("The stream of drinks is over")
  );

1. Creating an async observable from beers
2. Creating an async observable from soft drinks
3. Emitting the beers observable with next()
4. Emitting the soft drinks observable with next()
5. Unloading drinks from pallets into a merged observable
6. Subscribing to the merged observable

This script will produce the output that may look as follows (note that the drinks interleave):

Subscriber got Stella: 9.5
Subscriber got Coca Cola: 1.5
Subscriber got Sam Adams: 8.5
Subscriber got Fanta: 1.5
Subscriber got Bud Light: 6.5
Subscriber got Lemonade: 2.5
The stream of observables is over

To see it in CodePen visit this link.

Are there any other uses of the flatMap() operator besides unloading palettes of drinks? Another scenario where you’d want to use flatMap() is when you need to execute more than one HTTP request, where the result of the first request should be given to the second one. In Angular, HTTP requests return observables and without flatMap() this could be done (it a bad style) with nested subscribe() calls:

this.httpClient.get('/customers/123')
  .subscribe(customer => {
              this.httpClient.get(customer.orderUrl)
              .subscribe(response => this.order = response)
  })

The method httpClient.get() returns an observable, and the better way to write the above code is by using the flatMap() operator, which auto-subscribes and unwraps the content of the first observable and makes another HTTP request:

httpClient.get('./customers/123')
          .flatMap(customer => this.httpClient.get(customer.orderURL))
          .subscribe(response => this.order = response);

Since a flatMap() is a special case of map(), you can specify a transforming function while flattening the observables into a common stream. In the above example, we transform the value customer into a function call httpClient.get().

TIP: In RxJS, flatMap() is an alias of mergeMap() so these two operators have the same functionality.

Let’s consider one more example of using flatMap(). This example will be a modified version of the traders-orders example used in the article “Using RxJS Subject“. This example is written in TypeScript and it uses two Subject instances:

* traders – this Subject keeps track of traders
* orders – this Subject is declared inside the class Trader and keeps track of each order placed by a particular trader.

You’re the manager who wants to monitor all orders placed by all traders. Without flatMap(), you’d need to subscribe to traders (the outer observable) and create a nested subscription for orders (the inner observable) that each subject has. Using flatMap() allows you to write just one subscribe() call, which will be receiving the inner observables from each trader in one stream.

import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/mergeMap';

enum Action{
    Buy = 'BUY',
    Sell = 'SELL'
}

class Order{
    constructor(public orderId: number, public traderId: number, public stock: string, public shares: number, public action:Action){}
}

let traders = new Subject<Trader>();  // 1

class Trader {

    orders = new Subject<Order>();   // 2

    constructor(private traderId:number, public traderName:string){}
}

let tradersSubscriber = traders.subscribe(trader => console.log(`Trader ${trader.traderName} arrived`))

let ordersSubscriber = traders        // 3
  .flatMap(trader => trader.orders)   // 4
  .subscribe(ord =>      // 5
       console.log(`Got order from trader ${ord.traderId} to ${ord.action} ${ord.shares} shares of ${ord.stock}`));

let firstTrader = new Trader(1, 'Joe');
let secondTrader = new Trader(2, 'Mary');

traders.next(firstTrader);
traders.next(secondTrader);

let order1 = new Order(1, 1,'IBM',100,Action.Buy);
let order2 = new Order(2, 1,'AAPL',200,Action.Sell);
let order3 = new Order(3, 2,'MSFT',500,Action.Buy);

// Traders place orders
firstTrader.orders.next( order1);
firstTrader.orders.next( order2);
secondTrader.orders.next( order3);

1. Declare the Subject for traders
2. Each trader has its own Subject for orders
3. Starting with the outer observable traders
4. Extracting the inner observable from each Trader instance
5. The function subscribe() receives a stream of orders

In this version of the program, the class Trader doesn’t have a method placeOrder(). We just have the trader’s observable orders push the order to its observer by using the method next(). Remember, a Subject has both observable and observer.

The output of this program is shown next.

Trader Joe arrived
Trader Mary arrived
Got order from trader 1 to BUY 100 shares of IBM
Got order from trader 1 to SELL 200 shares of AAPL
Got order from trader 2 to BUY 500 shares of MSFT

In our example, the subscriber just prints the orders on the console, but in a real world app it could invoke another function that would be placing orders with the stock exchange for execution.

To see it in CodePen, follow this link. In the next article you’ll learn about a very useful operator switchMap().

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

RxJS Essentials. Part 1: Basic terms

Today, I’m starting a series of articles about programming with reactive extensions. This series is about the JavaScript RxJS library, but in the future, I’m planning to write a similar series about the RxJava – one of the Java versions of reactive extensions.

The first library of reactive extensions (Rx) was created by Erik Mejier in 2009. Rx.Net meant to be used for the apps written using the Microsoft’s .Net technology. Then the Rx extensions were ported to multiple languages, and in the JavaScript world, RxJS 5 is the current version of this library.

Let’s see what being reactive means in programming by considering a simple example.

let a1 = 2;

let b1 = 4;


let c1 = a1 + b1;  // c1 = 6

 

This code adds the values of the variables a1 and b1, and c1 is equal 6. Now let’s add a couple of lines to this code modifying the values of a1 and b1:

let a1 = 2;

let b1 = 4;


let c1 = a1 + b1;  // c1 = 6

 

a1 = 55;       // c1 = 6 but should be 59 
    
b1 = 20;       // c1 = 6 but should be 75

While the values of a1 and b1 changed, c1 didn’t react to these changes and its value is still 6. Of course, you can write a function that adds a1 and b1 and invokes it to get the latest value of c1, but this would be an imperative style of coding where you dictate when to invoke a function to calculate the sum.

Wouldn’t it be nice if c1 would be automatically recalulated on any a1 or b1 changes? Think of any spreadsheet program like Microsoft Excel, where you could put a formula =sum(a1, b1) into the c1 cell, and c1 would react immediately on the changes in a1 and b1. In other words, you don’t need to click on any button to refresh the value of c1 – the data are pushed to this sell.

In the reactive style of coding (as opposed to imperative one), the changes in data drive the invocation of your code. Reactive programming is about creating responsive event-driven applications, where an observable event stream is pushed to subscribers, which observe and handle the events.

In software engineering, Observer/Observable is a well-known pattern, and it’s a good fit in any asynchronous processing scenario. But reactive programming is a lot more than just an implementation of the Observer/Observable pattern. The observable streams can be canceled, they can notify about the end of a stream, and the data pushed to the subscriber can be transformed on the way from the data producer to the subscriber by applying one or more composable operators (you’ll see some of them in Part 2 of this series).

Getting familiar with RxJS terminology

We want to observe data, which means that there is some data producer that can be a server sending data using HTTP or WebSockets, a UI input field where the user enters some data, an accelerometer in a smart phone, et al. An observable is a function (or an object) on the client that gets the producer’s data and pushes them to the subscriber(s). UI An observer is an object (or a function) that knows how to handle the data elements pushed by the observable.

Hot and cold observables

There are two types of observables: hot and cold. The main difference is that a cold observable creates a data producer for each subscriber, while a hot observable creates a data producer first, and each subscriber gets the data from one producer starting from the moment of subscription.

Let’s compare watching a movie on Netflix vs going into a movie theater. Think of yourself as an observer. Anyone who decided to watch “Mission Impossible” on Netflix will get the entire movie regardless of when he or she hit the button play. Netflix creates a new producer to stream a movie just for you. This is a cold observable.

If you go to a movie theater and the showtime is 4PM, “the producer is created” at 4PM and the streaming begins. If some people (subscribers) were late to the show, they missed the beginning of the movie and will watch it starting from the moment of arrival. This is hot observable.

A cold observable starts producing data when some code invokes a subscribe() function on it. For example, your app may declare an observable providing a URL on the server to get certain products. The actual request will be made only when you subscribe to it. If another script will make the same request to the server, it’ll get the same set of data.

A hot observable produces data even if there are no subscribers interested in the data. For example, an accelerometer of your smartphone produces multiple data about the position of your device even if there no app that subscribes to this data. Or a server can produce the latest stock prices even if no user is interested in this stock.

The main players of RxJS

The main players of RxJS are:

* Observable – data stream that pushes data over time
* Observer – consumer of an observable stream
* Subscriber – connects observer with observable
* Operator – a function for the en-route data transformation

I’ll introduce each of these players in this series by showing examples of their use. For a complete coverage, refer to RxJS documentation.

Observable, observer, and subscriber

As stated earlier, an observable gets data from some data source (a socket, an array, UI events) one element at a time. To be precise, an observable knows how to do three things:

* Emit the next element to the observer
* Throw an error on the observer
* Inform the observer that the stream is over

Accordingly, an observer object provides up to three callbacks:

* The function to handle the next element emitted by the observable
* The function to handle errors thrown by the observable
* The function to handle the end of stream

The subscriber connects an observable and observer by invoking the method subscribe() and disconnects them by invoking unsubscribe(). A script that subscribes to an observable has to provide the observer object that knows what to do with the produced elements. Let’s say we created an observable represented by the variable someObservable and the observer represented by the variable myObserver. Then you can subscribe to such an observable as follows:

let mySubscription: Subscription = someObservable.subscribe(myObserver);

To cancel the subscription, invoke the unsubscribe() method:

mySubscription.unsubscribe();

How an observable can communicate with the provided observer? It does it by invoking the following functions on the observer object:

* next() to push the next data element to the observer

* error() to push the error message to the observer

* complete() to send a signal to the observer about end of stream

You’ll see an example of using these functions in the next article of this series.

Creating observables

RxJS offers multiple ways of creating an observable depending on the type of the data producer. As an example, the data producer a DOM event, a data collection, a custom function, a WebSocket and more. Below are some examples of the API to create and observable:

* Observable.of(1,2,3) – turns the sequence of numbers into an Observable
* Observable.create(myObserver) – returns an Observable that can invoke
 methods on myObserver that you will create and supply as an argument
* Observable.from(myArray) – converts an array represented by the variable myArray into an Observable. You can also use any an iterable data collection or a generator function as an argument of from().
* Observable.fromEvent(myInput, ‘keyup’) – converts the keyup event from some HTML element represented by myInput into an Observable
* Observable.interval(1000) – emits a sequential integer (0,1,2,3…) every second

Let’s create an observable that will emit 1,2, and 3 and subscribe to this observable:

Rx.Observable.of(1,2,3) 
    .subscribe(
        value => console.log(value),
        err => console.error(err),
        () => console.log("Streaming is over")
);

Note that we pass three fat arrow functions to subscribe(). These three functions are the implementation of our observer. The first function will be invoked for each element emitted by the observable. The second function will be invoked in case of an error providing the object representing the error. The third function takes no arguments and will be invoked when the observable stream is over. Running this code sample will produce the following output on the console:

1
2
3
Streaming is over

To see it in action in CodePen, follow this link. Open the console view at the bottom to see the output.

The basic terms are covered. In the next article of this series, I’ll introduce you to some RxJS operators that are used to transform the emitted items while they’re moving from observable to the observer.

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials”.

TypeScript Generics

TypeScript supports parameterized types, also known as generics, which can be used in a variety of scenarios. For example, you can create a function that can take values of any type, but during its invocation, in a particular context, you can explicitly specify a concrete type.

Take another example: an array can hold objects of any type, but you can specify which particular object types (for example, instances of Person) are allowed in an array. If you were to try to add an object of a different type, the TypeScript compiler would generate an error.

Generics syntax

The following code snippet declares a Person class, creates two instances of it, and stores them in the workers array declared with the generic type. Generic types are denoted by placing them in the angle brackets (for example, ).

class Person {
    name: string;
}

class Employee extends Person{
    department: number;
}

class Animal {
    breed: string;
}

let workers: Array<Person> = [];

workers[0] = new Person();
workers[1] = new Employee();
workers[2] = new Animal();  // compile-time error

Here we declare the Person, Employee, and Animal classes and a workers array with the generic type. By doing this, we announce our plans to store only instances of the class Person or its descendants. An attempt to store an instance of an Animal in the same array will result in a compile-time error.

Nominal and Structural type systems

After using generics in Java for 10 years, I quickly noticed that the syntax is the same and was about to check off this syntax element as “got it”. But it was a little too soon. While Java, C++, or C# use nomimal type system, TypeScript uses the structural one. In the nominal system, types are checked against their names, but in a structural system by their structure.

With the nominal type system the following line would result in an error:

let person: Person = new Animal();

With a structural type system, as long as the structures of the type are similar, you may get away with assigning an object of one type to a variable of another. Let’s illustrate it by adding the property name to the class Animal as seen on the screenshot below.

Now the TypeScript compiler doesn’t complain about assigning an Animal object to the variable of type Person. The variable of type Person expects an object that has a property name, and the Animal object has it. This is not to say that Person and Animal represent the same types, but these types a compatible. Trying to assign the Person object to a variable of type Animal will result in the compilation error “Property breed is missing in type Person”:

let worker: Animal = new Person(); // compilation error

Can you use generic types with any object or a function? No. The creator of the object or function has to allow this feature. If you open TypeScript’s type definition file (lib.d.ts) on GitHub and search for “interface Array,” you’ll see the declaration of the Array, as shown below.

The <T> in line 1008 means TypeScript allows you to declare a type parameter with Array and the compiler will check for the specific type provided in your program. The next code listing specifies this generic <T> parameter as <Person>. But because generics aren’t supported in JavaScript, you won’t see them in the code generated by the transpiler. It’s just an additional safety net for developers at compile time.

You can see another T in line 1022 in figure B.7. When generic types are specified with function arguments, no angle brackets are needed. But there’s no actual T type in TypeScript. The T here means the push method lets you push objects of a specific type into an array, as in the following example:

workers.push(new Person());

Creating your own parameterized types

You can create your own classes or functions that support generics as well. In the next listing, we defined an interface Comparator that declares a method compareTo() expecting the concrete type to be provided during this method invocation.

interface Comparator {                   // 1
    compareTo(value: T): number;
}

class Rectangle implements Comparator {    // 2

    constructor(private width: number, private height: number){};

    compareTo(value: Rectangle): number{   // 3
        if (this.width*this.height &gt;= value.width*value.height){
            return 1;}
        else  {
            return -1;
        }
    }
}

let rect1:Rectangle = new Rectangle(2,5);  
let rect2: Rectangle = new Rectangle(2,3);

rect1.compareTo(rect2)===1? console.log("rect1 is bigger"): 
                            console.log("rect1 is smaller") ;   // 4


class Programmer implements Comparator {    // 5

    constructor(public name: string, private salary: number){};

    compareTo(value: Programmer): number{  // 6
        if (this.salary &gt;= value.salary){
            return 1;}
        else  {
            return -1;
        }
    }
}

let prog1:Programmer = new Programmer("John",20000);
let prog2: Programmer = new Programmer("Alex",30000);

prog1.compareTo(prog2)===1? console.log(${prog1.name} is richer):
                           console.log(${prog1.name} is poorer) ;  // 7

1. Declare an interface Comparator with a generic type

2. Create a class that implements Comparator specifying the concrete type Rectangle

3. Implement the method for comparing rectangles

4.Compare rectangles (the type T is erased and replaced with Rectangle)

5. Create a class that implement Comparator specifying the concrete type Programmer

6.Implement the method for comparing programmers

7. Compare programmers (the type T is erased and replaced with Programmer)

Even though generics are erased during the JavaScript code generation, use them to minimize the number of runtime errors. When you use libraries or frameworks written in TypeScript, you have no choice but use generics to use the API provided by these libraries.

If you live in New York, stop by at the Java SIG meetup on August 23, 2017 where I’ll be delivering a presentation “TypeScript for Java Developers”.

JavaScript rest and spread operators

Back in 2015, the ECMAScript 6 spec was released and at the time of this writing, all major browsers (except the stubborn IE11) support its syntax. In this article, I’ll show you a couple of useful operators: rest and spread.

Due to lack of imagination, the creators of ES6 spec decided to use the same notation (…) for both rest and spread operators, but let’s not whine. If everything would be simple, our salaries would be lower. So let’s start with getting familiar with the rest operator.

Rest parameters

In ES5, writing a function with a variable number of parameters required using a special object called arguments. This object is similar to an array, and it contains values corresponding to the arguments passed to a function. The implicit arguments variable could be treated as a local variable in any function.

The rest operator is used to pass a variable number of arguments to a function, and it has to be the last one in the arguments list. If the name of the function argument starts with the three dots, the function will get the rest of the arguments in an array. The ES6 rest operator is represented by three dots (…).

For example, you can pass multiple customers to a function using a single variable name with a rest operator:

function processCustomers(...customers){
  // implementation of the function goes here
}

Inside this function, you can handle the argument customers the same way you’d handle any array. Imagine that you need to write a function to calculate taxes that must be invoked with the first argument income, followed by any number of arguments representing the names of the customers. The following code shows how you could process a variable number of arguments using first the ES5 and then the ES6 syntax. The calcTaxES5() function uses the object named arguments, and the function calcTaxES6() uses the ES6 rest operator:

// ES5 and arguments object
  function calcTaxES5(){

      console.log("ES5. Calculating tax for customers with the income ",
                             arguments[0]);   // income is the first element

      // extract an array starting from 2nd element
      var customers = [].slice.call(arguments, 1);

      customers.forEach(function (customer) {
          console.log("Processing ", customer);
      });
  }

  calcTaxES5(50000, "Smith", "Johnson", "McDonald");
  calcTaxES5(750000, "Olson", "Clinton");

// ES6 and rest operator
  function calcTaxES6(income, ...customers) {
      console.log("ES6. Calculating tax for customers with the income ", income);

      customers.forEach(function (customer) {
          console.log("Processing ", customer);
      });
  }

  calcTaxES6(50000, "Smith", "Johnson", "McDonald");
  calcTaxES6(750000, "Olson", "Clinton");

Both functions, calcTaxES5() and calcTaxES6() produce the same results:

ES5. Calculating tax for customers with the income 50000
Processing Smith
Processing Johnson
Processing McDonald
ES5. Calculating tax for customers with the income 750000
Processing Olson
Processing Clinton
ES6. Calculating tax for customers with the income 50000
Processing Smith
Processing Johnson
Processing McDonald
ES6. Calculating tax for customers with the income 750000
Processing Olson
Processing Clinton

See it in action on CodePen (click on the Console at the bottom to see the output): https://codepen.io/yfain/pen/WEjLwR?editors=0011

There’s a difference in handling customers though. Because the arguments object isn’t a real array, we had to create an array in the ES5 version by using the slice() and call() methods to extract the names of the customers starting from the second element in arguments. The ES6 version doesn’t require us to use these tricks because the rest operator gives you a regular array of customers. Using the rest arguments made the code simpler and more readable.

The spread operator

The ES6 spread operator is also represented by three dots (…) like the rest parameters, but if the rest operator can turn a variable number of parameters into an array, the spread operator can do the opposite: turn an array into a list of values or function parameters.

Say you have two arrays and you need to add the elements of the second array to the end of the first one. With the spread operator it’s one line of code:

array1.push(...array2);

You can also create a copy of an array as follows

let arrayCopy = [...myArray];

Finding a maximum value in the array is also easy with the spread operator:

const maxValue = Math.max(...myArray);

In some cases, you want to clone an object. In cases when you have an object that stores the state of your app, you may want to create a new object when one of the state properties changes. In other words, you don’t want to mutate the object but want to clone it with modification of one or more properties. One way to implement immutable objects is by using the Object.assign() function. The following code snippet will create a clone of the object first, and then will do another clone with changing the lastName at the same time:

// Clone with Object.assign()
const myObject = { name: "Mary" , lastName: "Smith"};
const clone = Object.assign({}, myObject);
console.log(clone); 

// Clone with modifying the `lastName`
const cloneModified = Object.assign({}, myObject, {lastName: "Lee"});
console.log( cloneModified); 

The spread operator offers a more concise syntax for achieving the same goals:

// Clone with spread
const cloneSpread = {...myObject};
console.log(cloneSpread);

// Clone with modifying the `lastName`
const cloneSpreadModified = {...myObject, lastName: "Lee"};
console.log(cloneSpreadModified);

See it in CodePen: https://codepen.io/yfain/pen/XaRGYa?editors=0011

If you haven’t been using spread and rest operators yet, it’s a big mistake. Huge.

This article is just an intro to using the rest and spread operators. For more info, read the docs here and here.

TypeScript: callable interfaces

TypeScript is a superset of JavaScript and over the last year it’s gaining popularity by leaps and bounds. Angular 2 and RxJS 5 are written in Typescript. I believe about a million of developers are using TypeScript today for app development (this is not official stats). I’m using TypeScript for more than a year and it’s so much more productive than JavaScript! For me (a Java developer), TypeScript makes a lot more sense than JavaScript. But if your main language was JavaScript, some of the TypeScript’s concepts might look foreign for you. I’m planning to write a couple of blogs illustrating TypeScript syntax.

Web browsers don’t understand TypeScript and there’re no plans to change this any time soon. So if you’ll write a program in TypeScript, it has to by transpiled (think compiled) into JavaScript first. I’m not going to discuss the TypeScript compiler here, but will be using the Playground, where you can write code fragments in TypeScript, and they’ll be immediately transpiled into JavaScript (it’s going to be the ECMAScript 5 version).

TypeScript supports different flavors of interfaces. Today we’ll get familiar with a callable interface that contains a bare function signature (a signature without a function name). I’ll show you the syntax first and then will explain how a callable interfaces are useful. The following example shows a bare function signature that takes one parameter of type number and returns a boolean.

(percent: number): boolean;

The bare function signature indicates that when this function will be implemented it’s going to be callable. So what’s the big deal? Let’s consider an example that declares IPayable interface, which will contain a bare function signature. In our company work employees and contractors that will be represented by a class Person. The rules for increasing pay of employees and contractors are different, and I’ll create separate functions that implement these rules. These functions will be passed as arguments to the constructor of the class Person and will be invoked inside the constructor of the Person instances.

interface IPayable { // <1>
    (percent: number): boolean;
}

class Person  {
    constructor(private validator: IPayable) { // <2>
    }

    increasePay(percent: number): boolean { // <3>
        return this.validator(percent);
    }
}

let forEmployees: IPayable = (percent) => { // <4>
        console.log("Increasing salary by ", percent);
        return true;
    };

let forContractors: IPayable = (percent) => { // <5>
    var increaseCap: number = 20;

    if (percent < increaseCap) {
      console.log("Increasing hourly rate by", percent);
      return true;
    } else {
      console.log("Sorry, the increase cap for contractors is ",
                                         increaseCap);
      return false;
    }
}

let workers: Array<Person> = [];

workers[0] = new Person(forEmployees); // <6>
workers[1] = new Person(forContractors);

workers.forEach(worker =>worker.increasePay(30)); // <7>

1. A callable interface that include a bare function signature.

2. We declare that the constructor of the Person class takes an implementation of the callable interface IPayable as an argument.

3. The increasePay() method invokes the bare function on the passed implementation of IPayable, supplying the pay increase value for validation.

4. The rules for salary increases for employees are implemented using the arrow function expression.

5. The rules for pay increases for contractors are implemented using the arrow function expression.

6. Instantiates two Person objects, passing different rules for pay increases.

7. Invokes increasePay() on each instance, validating the 30% pay increase.

First I’ll enter the above code in the TypeScript playground on the left, and the generated JavaScript code will be shown on the right (see http://bit.ly/2hUdsGn). Read the JavaScript code – it should help you understanding what’s going on. Note, that there are no traces of our IPayable interface on the right since JavaScript doesn’t support interfaces.

play

If you click on the button Run and open the browser’s console you’ll see the following output:

Increasing salary by 30
Sorry, the increase cap for contractors is 20

Cool. But in JavaScript you can also pass a function as an argument to a higher order function (constructor in our case), right?

Now imagine that you’re supposed to pass a function with a certain signature to a higher order function, but made a mistake and passed a wrong function. This will result in a runtime error.

Callable interfaces allow you to to catch this mistake during the development stage. For that we declare the signature of a function that has to be passed to the constructor of the instance of the Person object.

Now purposely introduce an error – declare a function with the wrong signature (do it on the left side at the playground):

let forTempWorkers = () => 
      console.log("Can't increase salary for temps"); 

Try to pass it to the constructor to a Person:

workers[0] = new Person(forTempWorkers); 

TypeScript will immediately highlight the above line as erroneous, and you’ll catch this error during dev time whereas in JavaScript this error would silently sneak into your code causing the app to blow up during the runtime.

play2

So callable interfaces are your friends, aren’t they?