Step #4 — Components

Angular2 places a strong emphasis on components. A typical application is made up of a tree of components starting from the root and scaling down to it’s child components. We will create our first component searchresult.component.ts under src/app/searchbox.

searchresult.component.ts

A couple of things to note here. The @Component decorator is used to indicate that the class at is a component containing the appropriate selector, template, and style. Again, for the sake of demonstration we will keep the the HTML and CSS inline within the component itself.

The @Input decorator defined in the class is responsible for passing data into the component itself. We have defined result to be of type Streamresult and thus we are able to use interpolation to display data to the component.

The next component we will create will display the search box and emit events based on the results. Lets create streamresultsearchbox.component.ts under src/app/searchbox . I will be breaking up the code in order to explain key concepts.

The template is a very simple search box to key in search results.

streamresultsearchbox.component.ts

streamresultsearchbox.component.ts

In the constructor of our class we have injected a StreamresultService instance and an instance of ElementRef in order to be able to access the underlying native DOM element.

The component we have created is a child component and will be able to pass values by including an @Output decorator on a variable of type EventEmitter . We have set two variables loading and result to capture the values of the custom events that are fired out.

Note that in the constructor we have implemented the OnInit interface. Component instances have a lifecycle as they are created, modified or destroyed. One of the lifecycle hook interfaces in the core angular library is the OnInit interface. Implementing this interface means we need to implement its hook method ngOnInit() . Angular will call this method shortly after the component has been created.

Next, lets fill out the ngOnInit() method. We would like this method to be called when the component is created and as such, a return value is not needed. Let us understand very carefully what is going on in the following block of code.

streamresultsearchbox.component.ts

Observable.fromEvent is a very flexible event converter and will convert keyup events into an observable stream(notice that the first argument this.el.nativeElement is the native DOM element that this component is attached to). The stream is then piped to a map operator which extracts the value of the keyup input(our query). The filter operator then filters the stream to store values that are not empty. debounceTime will set a time span of 200ms before another value is emitted from the source observable. The do observable will allow us to perform operations on the side. The operation we are performing is emitting true from the EventEmitter object to enable loading. The stream is then sent to the map operator to be processed by our search method defined in our service. The switch observable will consider the higher order Observable into a first-order Observable. This means that previous events are discarded and the most recent projected Observable is considered. Finally, the subscribe operator will act upon the search on a success, error, and completion condition. In each of these cases we can then disable loading as the result has been handled by the subscriber. Only in the success condition do we emit our result back to the components output event handler.

We will now create the parent component by creating twitchsearchcomponent.component.ts under src/app/searchbox . The parent component will utilize the selectors defined in the previous components.

twitchsearchstream.component.ts

Remember that the my-searchbox selector was previously defined inside StreamresultsearchboxComponent . Inside the selector tag there are two specific events that are emitted from the component. These two events are (loading)="loading=$event" and (results)="updateResults($event)" . When StreamresultsearchboxComponent emits a loading event the variable is set within the value of $event . Likewise, when a results event is emitted updateResults() is called with the value of $event . This has the effect of updating our components results instance variable.

The search-result selector was previously defined in SearchComponent . SearchComponent uses the @Input property result in order to retrieve a Streamresult object to display in its view. The search-result selector utilizes the ngFor directive to iterate through an array of Streamresult objects to bind an individual result object to display.

Now that we have completed coding our components section we will need to wire them to app.module.ts .

app.module.ts

Additionally, we will need to add the selector tag twitch-search from the TwitchsearchstreamComponent and place it inside app.component.html . The AppComponent is the root component of this application.