import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup } from 'angular2/common';
import {HTTP_PROVIDERS} from 'angular2/http';
import {DataService, DataServiceShape} from './data.service'; 
import 'rxjs/Rx';

@Component({
  selector: 'child',
  template : `
    <div class="col-md-6">
      <form [ngFormModel]="myFormNotShared"
        (ngSubmit)="makeNotSharedRequest(myFormNotShared.value)"
        class="ui form">
  
        <div class="field">
          <label for="postNumber">(NOT Shared Stream) Post Number</label>
          <input type="text"
            id="postNumber"
            placeholder="post number..."
            ngControl="postNumber">
  
          <button type="submit" class="ui button">Submit</button>
        </div>
      
      </form>
  
      <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">Not Shared Stream</h3>
        </div>
        <div class="panel-body">
          <table class="table">
            <tr><td>UserID:</td><td>{{(dataServiceObservableNotShared | async)?.userId}}</td></tr>
            <tr><td>ID:</td><td>{{(dataServiceObservableNotShared | async)?.id}}</td></tr>
            <tr><td>Title:</td><td>{{(dataServiceObservableNotShared | async)?.title}}</td></tr>
            <tr><td>Body:</td><td>{{(dataServiceObservableNotShared | async)?.body}}</td></tr>
          </table>
        </div>
      </div>
    </div>
    
    <div class="col-md-6">
      <form [ngFormModel]="myFormShared"
        (ngSubmit)="makeSharedRequest(myFormShared.value)"
        class="ui form">
  
        <div class="field">
          <label for="postNumber">(Shared Stream) Post Number</label>
          <input type="text"
            id="postNumber"
            placeholder="post number..."
            ngControl="postNumber">
  
          <button type="submit" class="ui button">Submit</button>
        </div>
      
      </form>
  
      <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">Shared Stream</h3>
        </div>
        <div class="panel-body">
          <table class="table">
            <tr><td>UserID:</td><td>{{(dataServiceObservableShared | async)?.userId}}</td></tr>
            <tr><td>ID:</td><td>{{(dataServiceObservableShared | async)?.id}}</td></tr>
            <tr><td>Title:</td><td>{{(dataServiceObservableShared | async)?.title}}</td></tr>
            <tr><td>Body:</td><td>{{(dataServiceObservableShared | async)?.body}}</td></tr>
          </table>
        </div>
      </div>
    </div>
  `,
  providers: [DataService],
  directives: [FORM_DIRECTIVES],
}) 
export class Child {
  myFormNotShared: ControlGroup;
  myFormShared: ControlGroup;
  dataServiceObservableNotShared: Observable<DataServiceShape>;
  dataServiceObservableShared: Observable<DataServiceShape>;

  constructor(fb: FormBuilder, private dataService: DataService) {
    this.myFormNotShared = fb.group({
      postNumber: ''
    });
    
    this.myFormShared = fb.group({
      postNumber: ''
    });    
  }  

  makeNotSharedRequest(form: any) {
    this.dataServiceObservableNotShared = this.dataService
        .getDataNotShared(this.myFormNotShared.controls.postNumber.value);
  }
  
  makeSharedRequest(form: any) {
    this.dataServiceObservableShared = this.dataService
        .getDataShared(this.myFormShared.controls.postNumber.value);
  }  
}
 
@Component({
  selector: 'my-app',
  template : '<child></child>',
  directives: [Child]
}) 
export class App {
}

bootstrap(App, [HTTP_PROVIDERS]);
<!DOCTYPE html>
<html>
  <head>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <title>Angular 2 Tour of Heroes</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- IE required polyfills, in this exact order -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
    <script src="https://npmcdn.com/angular2@2.0.0-beta.13/es6/dev/src/testing/shims_for_IE.js"></script>
   
    <script src="https://code.angularjs.org/2.0.0-beta.13/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://npmcdn.com/typescript@1.8.9/lib/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.13/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.13/angular2.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.13/http.dev.js"></script>
    <link data-require="bootstrap-css@*" data-semver="3.0.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
    <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {'app': {defaultExtension: 'ts'}} 
      });
        System.import('app/main')
              .then(null, console.error.bind(console));
    </script>
  </head> 

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>
import {Injectable} from 'angular2/core';
import {Http, Response, Headers, RequestOptions} from 'angular2/http';
import 'rxjs/Rx';

export interface DataServiceShape {
  userId: number,
  id: number,
  title: string,
  body: string,
  networkCalls: number
}

@Injectable()
export class DataService {
    constructor(private http: Http) { 
    }
    
    /**
     * Function will return an observable with the data requested. This can be shared across
     * subscribers and will not cause extra http traffic.
     */
    getDataShared(postNum: number): Observable<DataServiceShape> {
        let calls = 0;
         
        return this.http
                   .get('http://jsonplaceholder.typicode.com/posts/' + postNum)
                   .do(
                     () => {
                       console.log("side effect on shared");
                     }
                   )
                   .map(
                      (res) => {
                        let json = res.json();
                        calls++;
                        json.networkCalls = calls;
                        console.log(JSON.stringify(json));
                        return json;
                      })
                   .share();
          
    }

    /**
     * Function will return an observable with the data requested.
     * There is no share operator used here so each subscriber will result in the entire stream firing.
     */
    getDataNotShared(postNum: number): Observable<DataServiceShape> {
        let calls = 0;
                  
        return this.http
                   .get('http://jsonplaceholder.typicode.com/posts/' + postNum)
                   .do(
                     () => {
                       console.log("side effect on not shared");
                     }
                   )
                   .map(
                      (res) => {
                        let json = res.json();
                        calls++;
                        json.networkCalls = calls;
                        console.log(JSON.stringify(json));
                        return json;
                      });
          
    }  
  
}