Consuming events as Observables in Angular 2

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 2 years ago

In this video series we’ll take a look at Observables in Angular 2. We’ll figure out how they integrate with the http layer and how we can leverage their power to build a rock solid instant search with just a bunch of operators.

This first video walks you through the process of refactoring an existing solution to consume events from the template as Observables.

[00:00] In this video, we will learn how to consume events from our template as observables to build a richer user experience. Our starting point is a simple instance search with Wikipedia. As I type into the text box, we immediately see the results.

[00:12] Building this kind of thing, we'll face issues such as sending too many requests or getting a lot of auto-responses. We would like to solve these issues in a functional reactive way using observables.

[00:23] Before we get started with that, let's a quick look at the counter-implementation. We created our Wikipedia search service to perform JSONP request against the Wikipedia API. We injected the JSONP service and created a search method that takes string as a parameter.

[00:39] We then call out to the Wikipedia API to make the request. We also map the results of that. Our observable only carries an area of strings containing the results of our API request.

[00:50] Let's open up our app component. As we can see, it consumes the Wikipedia search service via dependency injection. It also exposes a method called Search to be invoked from the template.

[01:01] We also see that we are saving the results, our array, to an instance property called Items. Since our service is using the map operator, we are importing it here for application [inaudible] . Let's take a look at the template. It's a really basic markup, just enough to render an input box in the list.

[01:20] We see that we listen for the input event on our input box. Whenever that happens, we invoke the search method that we created on our component. We have a simple unsorted list with list items generated by NgFor of our collection of items.

[01:35] Now, that's all good. But in order to do things such as debouncing or deduplicating, we have to find a way to consume the changes of the input box as an observable of string. We can solve that using a subject that we have to import from the XJS library.

[01:50] Notice that the build runs while I'm typing, which is why we sometimes see an error in the output. A subject is an observable that we can subscribe to, but at the same time, we can also emit notifications on it. In a way, we can see it as a proxy between the actual event and an observable of that event.

[02:07] We need to create a property of type subject of string. Let's call it term$. Some people use a dollar suffix to indicate that a variable is an observable. We use this convention here, too, but that's really just a convention that some people use, so feel absolutely free to ignore it.

[02:24] Now that we have the subject, we need to make sure to subscribe to emitted changes and invoke our search method from here. We can do that either in the constructor or in the OnInit hook.

[02:33] It would be a bit cleaner to do that in the OnInit hook, but for the purpose of this exercise, we can keep it here. So far, there's no one actually raising notifications on our subject. Let's change our template to not directly invoke search, but call term$.next instead.

[02:50] By doing that, we are forwarding the input event into our subject, and that's it. Our subject still works the same way as before, but we are now proxying the user input through an observable, which is exactly what we need to proceed with our next refactoring.

Karstacian
Karstacian
~ 6 years ago

If I call the subscribe in the search function will it not create a new subscription each time I call search?

Creativestyle
Creativestyle
~ 6 years ago

It seems to me that there is a typing in : URLSerachParams (Search not Serach)

Oscar
Oscar
~ 6 years ago

+1, would be nice to have a github repo to this post so it can be updated. I am receiving no provider for connectionbackend! as an error with described code above

Corey
Corey
~ 6 years ago

Hi, found the issue with the error you noted above, I was importing the HttpModule and needed to import the JsonpModule under the 'imports' property in @NgModule decorator.

James
James
~ 6 years ago

for brevity:

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { WikipediaSearchService } from './wikipedia-search.service';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    JsonpModule
  ],
  providers: [
    WikipediaSearchService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Kemal Yalcinkaya
Kemal Yalcinkaya
~ 6 years ago

URLSerachParams seems to be deprecated by the Angular team, FYI

Varghese Pallathu
Varghese Pallathu
~ 5 years ago

I'm learning ngrx and came across a similar problem for fetching data from the server and displaying. Here is the code for it: https://github.com/ngrx/example-app/blob/master/src/app/effects/book.ts

My question is why the ngrx example is done differently with just Observable and not Subject. I also posted a question in stack overflow at http://stackoverflow.com/questions/42596635/why-takeuntil-is-necessary-in-this-ngrx-example

Dominik Sipowicz
Dominik Sipowicz
~ 5 years ago

Where is used map here in this lesson? import 'rxjs/add/operator/map';

carolina
carolina
~ 5 years ago

Hello, I received this bug running that code:

Refused to execute script from 'https://en.wikipedia.org/w/api.php?callback=ng_jsonp.__req0.finished' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

Could you help me? Thanks