title: Asynchronous call in angular using event emitter and services for cross-component communication
body: <p><strong>cannot store the value received from subscribe method in a template variable.</strong></p>
  
  <p><strong>photo-detail component</strong></p>
  
  <pre><code>import { Component, OnInit, Input } from "@angular/core";
  import { PhotoSevice } from "../photo.service";
  import { Photo } from "src/app/model/photo.model";
  
  @Component({
    selector: "app-photo-detail",
    templateUrl: "./photo-detail.component.html",
    styleUrls: ["./photo-detail.component.css"]
  })
  export class PhotoDetailComponent implements OnInit {
  
    url: string;
  
    constructor(private photoService: PhotoSevice) {
      this.photoService.photoSelected.subscribe(data =&gt; {
        this.url = data;
        console.log(this.url);
      });
      console.log(this.url);
    }
  
    ngOnInit() {
  
    }
  }
  </code></pre>
  
  <p>the outside console.log gives undefined, and nothing is rendered in the view, but inside the subscibe method i can see the value.So, how can i display it in my view?</p>
  
  <p><strong>photos component</strong></p>
  
  <pre><code>import { Component, OnInit } from "@angular/core";
  import { ActivatedRoute, Params, Router } from "@angular/router";
  import { FnParam } from "@angular/compiler/src/output/output_ast";
  import { AlbumService } from "../service/album.service";
  import { Photo } from "../model/photo.model";
  import { PhotoSevice } from "./photo.service";
  
  @Component({
    selector: "app-photos",
    templateUrl: "./photos.component.html",
    styleUrls: ["./photos.component.css"]
  })
  export class PhotosComponent implements OnInit {
    selectedAlbumId: string;
    photoList: Photo[] = [];
    photoSelected: Photo;
    isLoading: Boolean;
    constructor(
      private rout: ActivatedRoute,
      private albumService: AlbumService,
      private router: Router,
      private photoService: PhotoSevice
    ) { }
  
    ngOnInit() {
      this.isLoading = true;
      this.rout.params.subscribe((params: Params) =&gt; {
        this.selectedAlbumId = params["id"];
        this.getPhotos(this.selectedAlbumId);
      });
    }
  
    getPhotos(id: string) {
      this.albumService.fetchPhotos(this.selectedAlbumId).subscribe(photo =&gt; {
        this.photoList = photo;
        this.isLoading = false;
      });
    }
  
    displayPhoto(url: string, title: string) {
  
      console.log(url);
      this.photoService.photoSelected.emit(url);
      this.router.navigate(["/photo-detail"]);
    }
  }
  </code></pre>
  
  <p>please explain me how this works and how to work around it so that i can store and display the value received from subscribing and asynchronous call in a template view.</p>
  
  <p>here are the views of the two components---</p>
  
  <p><strong>photo.component.html</strong></p>
  
  <pre><code>&lt;div *ngIf="isLoading"&gt;
    &lt;h3&gt;Loading...&lt;/h3&gt;
  &lt;/div&gt;
  
  &lt;div class="container" *ngIf="!isLoading"&gt;
    &lt;div class="card-columns"&gt;
      &lt;div *ngFor="let photo of photoList" class="card"&gt;
        &lt;img
          class="card-img-top"
          src="{{ photo.thumbnailUrl }}"
          alt="https://source.unsplash.com/random/300x200"
        /&gt;
        &lt;div class="card-body"&gt;
          &lt;a
            class="btn btn-primary btn-block"
            (click)="displayPhoto(photo.url, photo.title)"
            &gt;Enlarge Image&lt;/a
          &gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  
  </code></pre>
  
  <p><strong>photo-detail.component.ts</strong></p>
  
  <pre><code>&lt;div class="container"&gt;
    &lt;div class="card-columns"&gt;
      &lt;div class="card"&gt;
        &lt;img class="card-img-top" src="{{ url }}" /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  
  </code></pre>
  
  <p><strong>photo.service.ts</strong></p>
  
  <pre><code>import { Injectable } from "@angular/core";
  import { EventEmitter } from "@angular/core";
  
  @Injectable({ providedIn: "root" })
  export class PhotoSevice {
    photoSelected = new EventEmitter();
   // urlService: string;
  }
  
  </code></pre>
  
  <p>here is a link to my github repo, i have kept the code in comments and used a different approach there.
  If you check the albums component there also i have subscribed to http request and assigned the value in the template variable of albums component.
  there also the value comes as undefined oustide the subscibe method, but i am able to access it in template.</p>
  
  <p><a href="https://github.com/Arpan619Banerjee/angular-accelerate" rel="nofollow noreferrer">https://github.com/Arpan619Banerjee/angular-accelerate</a></p>
  
  <p><strong>here are the details of albums component and service</strong>
  pls compare this with the event emitter case and explain me whats the difference--
  <strong>albums.component.ts</strong></p>
  
  <pre><code>import { Component, OnInit } from "@angular/core";
  import { AlbumService } from "../service/album.service";
  import { Album } from "../model/album.model";
  
  @Component({
    selector: "app-albums",
    templateUrl: "./albums.component.html",
    styleUrls: ["./albums.component.css"]
  })
  export class AlbumsComponent implements OnInit {
    constructor(private albumService: AlbumService) {}
    listAlbums: Album[] = [];
    isLoading: Boolean;
  
    ngOnInit() {
      this.isLoading = true;
      this.getAlbums();
    }
  
    getAlbums() {
      this.albumService.fetchAlbums().subscribe(data =&gt; {
        this.listAlbums = data;
        console.log("inside subscibe method--&gt;" + this.listAlbums); // we have data here
        this.isLoading = false;
      });
      console.log("outside subscribe method-----&gt;" + this.listAlbums); //empty list==== but somehow we have the value in the view , this doesn t work
      //for my photo and photo-detail component.
    }
  }
  
  </code></pre>
  
  <p><strong>albums.component.html</strong></p>
  
  <pre><code>&lt;div *ngIf="isLoading"&gt;
    &lt;h3&gt;Loading...&lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="container" *ngIf="!isLoading"&gt;
    &lt;h3&gt;Albums&lt;/h3&gt;
    &lt;app-album-details
      [albumDetail]="album"
      *ngFor="let album of listAlbums"
    &gt;&lt;/app-album-details&gt;
  &lt;/div&gt;
  
  </code></pre>
  
  <p><strong>album.service.ts</strong></p>
  
  <pre><code>import { Injectable } from "@angular/core";
  import { HttpClient, HttpParams } from "@angular/common/http";
  import { map, tap } from "rxjs/operators";
  import { Album } from "../model/album.model";
  import { Observable } from "rxjs";
  import { UserName } from "../model/user.model";
  
  @Injectable({ providedIn: "root" })
  export class AlbumService {
    constructor(private http: HttpClient) {}
    albumUrl = "http://jsonplaceholder.typicode.com/albums";
    userUrl = "http://jsonplaceholder.typicode.com/users?id=";
    photoUrl = "http://jsonplaceholder.typicode.com/photos";
  
    //get the album title along with the user name
    fetchAlbums(): Observable&lt;any&gt; {
      return this.http.get&lt;Album[]&gt;(this.albumUrl).pipe(
        tap(albums =&gt; {
          albums.map((album: { userId: String; userName: String }) =&gt; {
            this.fetchUsers(album.userId).subscribe((user: any) =&gt; {
              album.userName = user[0].username;
            });
          });
          // console.log(albums);
        })
      );
    }
  
    //get the user name of the particular album with the help of userId property in albums
    fetchUsers(id: String): Observable&lt;any&gt; {
      //let userId = new HttpParams().set("userId", id);
      return this.http.get(this.userUrl + id);
    }
  
    //get the photos of a particular album using the albumId
    fetchPhotos(id: string): Observable&lt;any&gt; {
      let selectedId = new HttpParams().set("albumId", id);
      return this.http.get(this.photoUrl, {
        params: selectedId
      });
    }
  }
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/6ZGId.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6ZGId.png" alt="enter image description here"></a></p>
  
  <p>I have added console logs in the even emitters as told in the comments and this is the behavior i got which is expected.</p>