Angular 2.0 and > – How do components communicate with each other

As we are already aware Angular follows component philosophy, it is component based, everything is a component. Components are the main way we build and specify elements and logic on the page. We define root component and then multiple child components to that root component and then grand child components to child components and this continues which builds a component hierarchy. So obviously in this components have to talk with each other to pass data or for notifications, there are 3 patterns of communication over here

  1. Parent to child
  2. Child to parent
  3. Communication between sibling components

1. Parent to Child

This can be achieved using the @Input, to define an input for a component, we use the @Input decorator.

1-Ang2-Comp-Comm

For example, our component needs a counter argument to initialize the counter in child component

Now we will define the @Input counter in component as below

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() counter = 0;
  @Output() childComponentNotification = new EventEmitter();
  constructor() { }

  ngOnInit() {
  }

  incrementCounter(){
    this.counter++;
    this.childComponentNotification.emit(this.counter);
  }
}

HTML of child component looks some thing like this

2-Ang2-Comp-Comm

As you can we have child component which has counter as Input propert from parent component, this input initializes the child components internal counter and whenever user clicks on the button in the child component

2. Child to Parent

Now when the user clicks on the button on child component it increments the counter, this increments needs to be notified to the parent component this is where @Output comes in to the picture. To be able to use our Output, we need to import and bind a new instance of the EventEmitter to it.   We have to call .emit() to emit an event to the parent. So in the above case we hook in the @Output childComponentNotification to the event onChildComponentNotification event function which has been defined in the parent component.. Here is the snippet.

import { Component, NgZone } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Parent Component';
  private childCounter: Number;
  private childCounterRefInParent: Number;
  constructor(private ngZoneService: NgZone) {
    this.childCounter = 0;
    this.childCounterRefInParent = 0;
  }

  onChildNotificationReceived(childCounter: Number) {
    this.childCounterRefInParent = childCounter;
  }
}

HTML for app component of parent component display the incremented counter from child component.Incremented counter is been passed as event parameter.

3-Ang2-Comp-Comm

Advertisements

ngZone === $scope.$apply(). What is equivalent of $scope.$apply() in angular 2 and beyond…..

ngZone is an injectable service for executing work inside or outside of the Angular zone. The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don’t require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed, these tasks can reenter the Angular zone via run.

In Angular 2, change detection is automatic as opposed to Angular 1 that applys the change detection with the help of methods like $scope.$watch() and $scope.$digest().

Under the hood, Angular 2 uses something called Zones. In a nutshell, Zone.js intercepts all of the asynchronous APIs in the browser by monkey patching them.

Monkey patching is a technique to override, extend or even suppress the default behavior of a code segment without changing its source code. So when we call something like setTimeout — Angular 2 knows that and can trigger change detection and decide if she needs to update the DOM because setTimeout() is monkey patched.

Angular 2 gives us the ability to escape from change detection with the help of the ngZone service that exposes the runOutsideAngular method. Running functions via runOutsideAngular allows you to escape Angular’s zone and do work that doesn’t trigger Angular change-detection or is subject to Angular’s error handling.

We need to pass a function to this method and any future tasks scheduled from within this function will continue executing from outside of the Angular zone.

import { Component, NgZone } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';

  constructor(private ngZoneService: NgZone){
    this.ngZoneService.runOutsideAngular(()=>{
      //Execute all Your code over here which needs to be executed 
      // outside of angular context
      // ...
      // ...
      // ...
      // ...
      // ...

      //Reenter 
      this,ngZoneService.run(()=>{
          console.log("Reenetering angular context....")
      });

    });
  }
}

 

Change detection in Angular (Obviously 2.0 & greater)

Let me define first what change detection is, in simple terms any state change that needs to be propagated to UI and ice versa. Now the application state changes can happen in   following ways which apparently all are asynchronous in nature.

  • Events – Click, selection changed, keyup
  • Remote API Ajax Calls(XHR)
  • Timers – setTimeout(), setInterval()

Now for sure we know what how the application state change happens but there is still work of notifying Angular that state has changed and do the further magic. After all in the angular code we are still using Native API’s (like setTimeOut…) there are no angular specific API’s. So there is some thing called as Zone.js which does all the magic. You must have seen zone references whenever u see any error in the console window.

So what are zone and how do they work?

As one liner definition we can say that Zones are basically an execution context for asynchronous operations. Zones basically monkey patch these native methods and provide hooks for executing change detection.  As soon as we embed zone.js in our site, pretty much all methods that cause asynchronous operations are monkey-patched to run in a new zone. For example, when we call setTimeout() we actually call Zone.setTimeout().

So now we know that zones have hooks for asynchronous operation but how does it marry with angular, answer lies in to the ApplicationRef class and source code below, it simplified version of the code….

class ApplicationRef {

  changeDetectorRefs:ChangeDetectorRef[] = [];

  constructor(private zone: NgZone) {
    this.zone.onTurnDone
      .subscribe(() => this.zone.run(() => this.tick());
  }

  tick() {
    this.changeDetectorRefs
      .forEach((ref) => ref.detectChanges());
  }
}

ApplicationRef listens to NgZones onTurnDone event. Whenever this event is fired, it executes a tick() function which essentially performs change detection.

In Angular, each component has its own change detector. So in the component tree each component will have its own change detector. This allows us to control, for each component individually, how and when change detection is performed

ChnageDetection1

Let us assume that in the component tree an event has been triggered in the Child 2.1 component.  As mentioned earlier zones have hook in to these event handlers, zones execute the given handler and notify Angular when it is done, which eventually causes Angular to perform change detection. Now for angular change detection always flows from top to bottom. Change detection is also always performed from top to bottom for every single component, every single time, starting from the root component

ChnageDetection2ChnageDetection3ChnageDetection4

This is much more predictable change detection than in Angular JS where it used to digest loop or cycle.

CD (change detection) gets stable after a one pass, if one of our components causes any additional side effects after the first run during change detection, then angular will throw an exception.

Now that we have talked @ Change detectors in Angular but what are these Change detectors, well these are not one fit all generic classes which does the change detection for all components. Angular creates CD classes at runtime for each component, which are monomorphic, because they know exactly what the shape of the component’s model is.  Monomorphic are king of opposite of polymorphic which do not have any runt time overrides or sub types.

Angular also gives control of the change detection, if we wish to. We can tell angular to run CD only for the part of the component hierarchy tree. This can be achieved with 2 things

  • Immutable data structures
  • Observables

Lets consider optimization through Immutability first, consider the followin component

import { Component, OnInit } from '@angular/core';
import { UtilityService } from './../services/utility.service';
@Component({
  templateUrl: ''
})
export class GrandChildComponent implements OnInit {
  public greatGrandChildDetails: GreatGrandChildDetails;
  public currentDateTime : string;
  constructor(private utilService: UtilityService) {
    this.currentDateTime = this.utilService.currentDateTime.toISOString();
    this.greatGrandChildDetails = new GreatGrandChildDetails();
    this.greatGrandChildDetails.firstName = "Amol";
    this.greatGrandChildDetails.lastName = "Gote";
   }

  ngOnInit() {
  }

  changeGrandChildData(){
    this.greatGrandChildDetails.firstName = "John";
    this.greatGrandChildDetails.lastName = "Doe";
  }

}

export class GreatGrandChildDetails{
  firstName: string;
  lastName: string;
}

GrandChildComponent uses as a child component, which has an input property details. We’re passing data to that component with GrandChildComponent own greatGrandChildDetails property. greatGrandChildDetails is an object with two properties. In addition, there’s a method changeGreatGrandChildData(), which changes the first name and last name of greatGrandChildDetails, No magic going on here.
The important part is that changeGreatGrandChildData() mutates greatGrandChildDetails, by changing its first and last name property. Even though that property is going to be changed, the greatGrandChildDetails reference itself stays the same.
What happens when change detection is performed, assuming that some event causes changeGreatGrandChildData() to be executed? First, greatGrandChildDetails.firstName and greatGrandChildDetails.lastName gets changed, and then it’s passed to . ’s change detector. It now checks if the given details (greatGrandChildDetails) is still the same as before, and yes, it is (reference hasn’t changed), however, the first and last name property has changed, so Angular will perform change detection for that object nonetheless. Because objects are mutable by default in JavaScript (except for primitives), Angular has to be conservative and run change detection every single time for every component when an event happens. This is where immutable data structures come into play.

Immutable objects cannot be changed and we have to change then we have change the reference.

this.greatGrandChildDetails = Immutable.create({
              firstName: 'Amol',
              lastName: 'Gote'
            });

this.greatGrandChildDetailsNew = this.greatGrandChildDetails
                                  .set('firstName', 'John');

In the above case Immutable.create is just sample API to create Immutable, you can use any library to create immutable objects. Now when I am changing the first Name property then it is going to return a whole new reference to the object.

this.greatGrandChildDetails !=== this.greatGrandChildDetailsNew from a reference perspective both are pointing to different references. If we use immutable objects in our Angular app, all we need to do is tell Angular that a component can skip change detection, if the input has not changed, let’s look at the great-grand-child component.

Immutable-Component

We can skip entire subtrees when immutable objects are used and Angular is informed accordingly.
Immutable
ChangeDetectionStrategy.OnPush – This will inform Angular that our component only depends on its inputs and that any object that is passed to it should be considered immutable.

Now let’s talk @ Observables

Observables give us some guarantees of when a change has happened, unlike immutable objects, they don’t give us new references, instead, they fire events we can subscribe to in order to react to them.

Lets look at this example

import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
import { UtilityService } from './../services/utility.service';
@Component({
  template: '{{hitCounter}}',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {

  @Input() addChildItemStream:Observable;
  public hitCounter : number = 0;

  ngOnInit() {
    this.addChildItemStream.subscribe(() => {
      this.hitCounter++; 
    })
  }

}

We set the change detection strategy to OnPush, so change detection isn’t performed all the time, only when the component’s input properties change, the reference of addChildItemStream will never change, so change detection is never performed for this component’s subtree. This is a problem because the component subscribes to that stream in its ngOnInit life cycle hook and increments the counter. This is application state change and we want to have this reflected in our view. This is where ChangeDetectorRef comes to the rescue, it has an API markForCheck(), it marks the path from our component until root to be checked for the next change detection run, it simply iterates upwards and enables checks for every parent component up to the root.

import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core';
import { UtilityService } from './../services/utility.service';
@Component({
  template: '{{hitCounter}}',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {

  @Input() addChildItemStream:Observable<any>;
  public hitCounter : number = 0;
  constructor(private changeDetector: ChangeDetectorRef) {

  }

  ngOnInit() {
    this.addChildItemStream.subscribe(() => {
      this.hitCounter++; // application state changed
      this.changeDetector.markForCheck();
    })
  }

}

Typeaheads – Avoid Frequent Backend calls with RxJS debounce……

If you are implementing any typeaheads like when as user types in and you display the result immediately, obviously for displaying these results you are back end API calls from your front end angular app. Now there is one gotcha over typically the way you do it on key for some number of characters (for.e.g 3 characters) you start making back end api calls for each key press, which poses challenge in itself. So what if if we have an way we make an API call when user user stops typing in or with some time delays. This is where RxJS debounceTime comes to rescue.

As explained earlier  RxJS allows you to work with asynchronous data streams. Now once a value is emitted from stream, debounce will pause its emission for specific X amount of time to see if another value is emitted, it is blocking the stream during this time. If a new value is emitted during the debounce time then the timer is restarted and debounce waits again for the full time. If its timer expires without any new value being emitted, it let the latest value pass. This can be very helpful in the scenarios of type-ahead.

Here is the sample screen shot.

Debounce sample

So as I type in I making calls to to Git Hub User API and displaying the HTML URL. So over here I have stopped thrice so three results.

Here is the code snippet for component and Html Template

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/pluck';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit  {
  gitUsers: string[];
  title = 'app works!';
  @ViewChild('searchInput') searchInput: ElementRef;

  constructor (private http: Http) {
    this.gitUsers = new Array<string>();
  }

  ngAfterViewInit(){
    console.log(this.searchInput.nativeElement.value);
    Observable.fromEvent(this.searchInput.nativeElement, 'keyup')
      .debounceTime(500)
      .pluck('target', 'value')
      .filter((value: string) => value.trim().length > 0)
      .map((values: string) => {
        return this.gitUsersSearch(values)
      })
      .forEach(data => {
          data.subscribe(
            (result: Response) => {
              console.log(result);
              let responseBody = result.json();    
              this.gitUsers.push(responseBody.html_url);
              console.log(this.gitUsers);
            }
          );
      });
  }
  gitUsersSearch(searchTerm: string){
    console.log("Inside gitUsersSearch");      
    return this.http.get("https://api.github.com/users/" + searchTerm);
  }
}

Html Template

Debounce sample2

So apart from debounceTime I have used following additional API’s from Observables

  • Pluck –  It returns an Observable containing the value of a specified nested property from all elements in the Observable sequence. If a property can’t be resolved, it will return undefined for that value.
  • filter –Filter operator filters an Observable by only allowing items through that pass a test that you specify in the form of a predicate function.

Exception Handling in Task Parallel Library

Typically when you are using Task parallel library in .NET, the thread on which task would get executed would be different thread , so if you have  you have try catch blocked wrapped for the Task call and have wait on the task then you can catch the exception but it will not show the original exception which was raised. Take for e.g. below

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Worker worker = new Worker();
                var task = Task.Factory.StartNew(worker.DoWork);
                task.Wait();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.GetType());
            }
            Console.ReadLine();
        }
    }

    public class Worker
    {
        public void DoWork()
        {
            throw new Exception("Testing TPL Library Exception Handling");
        }
    }

In the above case the output would be

One or more errors occurred.
System.AggregateException

To propagate all the exceptions back to the calling thread, the Task infrastructure wraps them in an AggregateException instance. The AggregateException exception has an InnerExceptions property that can be enumerated to examine all the original exceptions that were thrown, and handle (or not handle) each one individually. You can also handle the original exceptions by using the System.AggregateException.Handle method.
Even if only one exception is thrown, it is still wrapped in an AggregateException exception

So we will modify the code to accommodate the AggregateException

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Worker worker = new Worker();
                var task = Task.Factory.StartNew(worker.DoWork);
                task.Wait();
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.InnerExceptions)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.GetType());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.GetType());
            }
            Console.ReadLine();
        }
    }

    public class Worker
    {
        public void DoWork()
        {
            throw new Exception("Testing TPL Library Exception Handling");
        }
    }

 

In this case output would be
Testing TPL Library Exception Handling
System.Exception

HTH

Hierarchical Dependency Injection in Angular

DI (Dependency Injection) in Angular 2.0 is hierarchical in nature, for dependency injection to be able to create instances for you, you need to register providers for these classes (or other values) somewhere. and you can configure providers for DI at different levels

  • For the whole application when bootstrapping it. In this cases, all sub injectors (the component ones) will see this provider and share the instance associated with. When interacting, it will be the same instance
  • For a specific component and its sub components. Same as before but for à specific component. Other components won’t see this provider. If you redefine something defined above (when bootstrapping for example), this provider will be used instead. So you can override things. If a provider is registered in one of the child components a new (different) instance is provided for descendants of this component.
  • If a component requests an instance (by a constructor parameter), DI looks “upwards” the component tree (starting from leaf towards the root) and takes the first provider it finds. If an instance for this provider was already created previously, this instance is used, otherwise a new instance is created.

For e.g. In the bbelow sample we have hirerachy of components in this manner

App Component => Parent Component => Child Component => Grand Child component

Comp-Hirerarchy1

All the components share a Utility Service which looks some thing like this 

import { Injectable } from '@angular/core';

@Injectable()
export class UtilityService {
  public currentDateTime : Date;
  constructor() { 
    console.log("Inside Utility Service Constructor");
    this.currentDateTime = new Date();
  }

}

As you can see service is not doing any thing special it just has a date time variable which gets initialized when instance of that service is created.

These components are rendered dynamically based on button clicks in following sequence
Comp-Hirerarchy2

Click on Show hide it renders the Parent component, in this case parent component is using same instance as that of App Component, it is had not provided its own provider. So the date time which is displayed is same in app and parent component.

Comp-Hirerarchy3

Click on show hide of parent component it renders Child Component, not in this case it will display a new date time as we have specified provider of Utility service inside Child Component.

Comp-Hirerarchy4

import { Component, OnInit } from '@angular/core';
import { UtilityService } from './../services/utility.service';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css'],
  providers: [UtilityService]
})
export class ChildComponent implements OnInit {
  public currentDateTime : string;
  constructor(private utilService: UtilityService) {
    this.currentDateTime = this.utilService.currentDateTime.toISOString();
   }

  ngOnInit() {
  }
}

Now the grand child component is not defining it own provider, so it is using the same instance as that of its ancestor which in this case is child component. So the date time which is displayed in the child component and grand child component is same.

Providers are usually singleton (one instance) objects, that other objects have access to through dependency injection (DI).  Provider is Angular’s term for these reusable objects (dependencies).

Provider lookup – When a component or directive has a dependency (constructor parameter), DI starts looking on this components injector for providers, if it has one it requests the instance from this provider and injects it. If the injector doesn’t have a provider for the requested key (type) then the parent injector is visited, up to the root (bootstrap) until a provider is found and its instance can be injected. (if no provider is found DI throws an error).

We often declare providers in angular this way:

providers: [AnyService]

Which is short cut for representing this

[new Provider(AnyService, {useClass: AnyService})]

 

Complete source code can be found at Github

ASP.NET Web API and Streaming Video Content

Below post explains how to stream video content through ASP.Net Web API’s, below is the code for Video Controller which inherits from API Controller. API show both GET and POST approaches.

Main thing to concentrate in the code is usage of Push Stream Content. PushStreamContent enables option to send data in small stream packets which then could be used on client side to stream videos, download large files etc.

    /// API Controller for streaming video files.
    public class VideoController : ApiController
    {
        private const string videoFilePath = "~/Movies/";

        /// Gets the live video.
        [HttpGet]
        [Route("api/video/live")]
        public IHttpActionResult GetLiveVideo(string videoFileId, string fileName)
        {
            string filePath = Path.Combine(HttpContext.Current.Server.MapPath(videoFilePath), fileName);
            return new VideoFileActionResult(filePath);
        }

        /// Gets the live video using post.
        /// The request.
        [HttpPost]
        [Route("api/video/live")]
        public IHttpActionResult GetLiveVideoPost(VideoFileDownloadRequest request)
        {
            string filePath = Path.Combine(HttpContext.Current.Server.MapPath(videoFilePath), request.FileName);
            return new VideoFileActionResult(filePath);
        }
    }

    /// Action Result for Returning Stream
    public class VideoFileActionResult : IHttpActionResult
    {
        private const long BufferLength = 65536;
        public VideoFileActionResult(string videoFilePath)
        {
            this.Filepath = videoFilePath;
        }

        public string Filepath { get; private set; }

        public Task ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = new HttpResponseMessage();
            FileInfo fileInfo = new FileInfo(this.Filepath);
            long totalLength = fileInfo.Length;
            response.Content = new PushStreamContent((outputStream, httpContent, transportContext) =>
                {
                    OnStreamConnected(outputStream, httpContent, transportContext);
                });

            response.Content.Headers.ContentLength = totalLength;
            return Task.FromResult(response);
        }

        private async void OnStreamConnected(Stream outputStream, HttpContent content, TransportContext context)
        {
            try
            {
                var buffer = new byte[BufferLength];

                using (var nypdVideo = File.Open(this.Filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var videoLength = (int)nypdVideo.Length;
                    var videoBytesRead = 1;

                    while (videoLength > 0 && videoBytesRead > 0)
                    {
                        videoBytesRead = nypdVideo.Read(buffer, 0, Math.Min(videoLength, buffer.Length));
                        await outputStream.WriteAsync(buffer, 0, videoBytesRead);
                        videoLength -= videoBytesRead;
                    }
                }
            }
            catch (HttpException ex)
            {
                return;
            }
            finally
            {
                // Close output stream as we are done
                outputStream.Close();
            }
        }
    }

 

On the client side you can view the video file using below code snippet

<video width="480" height="320" controls="controls" autoplay="autoplay">
        <source src="api/video/live?videoFileId=1001&fileName=sampleVideo.mp4" type="video/mp4">
    </video>