Observables are a key concept in Angular 4. The term is derived from the Observer Pattern which is used to observe state changes in objects that emit data (Observers). In other words, objects act accordingly based on something that they observe (the database changes, so the element says 'Database is updated'). This is an example use case of an observable being observed and why it is useful.

What is an Observer?

Angular uses observers by utilising functions in RxJS[1], which is a popular library for Reactive Programming[2]. Reactive Programming is a paradigm that deals with events by reacting to changes on an objects state; there are different definitions out there, but this is in keeping with the general consensus.

Practical example of an Observer

Let's dive straight into a practical example of observables in Angular 4:

We won't be covering the imports, so simply import the relevant modules (Observable, map, catch, etc)

@Injectable()
export class RecipeService {

  private url: string = CONFIG.URL; // an endpoint, e.g 'https://fake-api.recipes.com/search?q=chicken'

  constructor(private http: Http) { }

  getRecipeData() : Observable<IRecipe[]> {
    return this.http.get(this.url)
               .map((resp: Response) => resp.json())
               .catch(this.handleError);
  }

  handleError(error: any) {
      console.error(error);
      return Observable.throw(error.json().error || 'Server error');
  }

}

The code above contains a function that fetches recipe data from a fake api and maps the response into JSON (this uses the HTTP module to fetch the data). Let us look further into this function[3]. According to the documentation, http.get() returns Observable<Response>, which is an Observable of the type Response (contains status codes, etc). This means that this function getRecipeData() can be subscribed to in the following way:

  ngOnInit() {

    this.recipeService.getRecipeData()
    .subscribe((data: IRecipe[]) => this.recipes = data);
    console.log(this.recipes);
    
  }

Naturally we can now handle the data as desired (map, toUpperCase, etc), which can be done in this way:

    this.recipeService.getRecipeData()
    .subscribe((data: IRecipe[]) => {
      data[name].toUpperCase(); // JERK CHICKEN
    });

This example used a function from Angular which created its own observable and abstracted much of the setup away from us. This is why we can simply subscribe to the value of the observable; to reiterate, this function which returns an observable is http.get(). Additionally, the subscribe() takes three arguments, namely next, error and completed which I will cover in my next post.

In closing, there are several other function built into Angular that return observables, check out the documentation. Such functions can be subscribed to as shown in the examples above. RxJS can be used to create custom observables, but this post only covers Angular's built in observables and how to use them. However knowing how to use functions in Angular that return observables is highly useful when developing with Angular.

References:

  • [1] http://reactivex.io/rxjs/
  • [2] https://en.wikipedia.org/wiki/Reactive_programming
  • [3] https://angular.io/api/http/Http#get