1

I have a component which displays a list of objects. When one of the elements in this list is clicked, I would like to to pass the object to another component that is on another page.

So basically list component -> service component -> details component -> display the clicked list component details

List Component:

setCurrentMovie(movie: IMovie){
    this._currentMovieService.setCurrentMovie(movie);
  }

Service class which I am using to track the current object

  setCurrentMovie(movie: IMovie){
    this.movie = movie;
  }
  getCurrentMovie(): Observable<IMovie>{
    return of(this.movie);
  }

Details Component which displays the current object

getCurrentMovie(){
 console.log(this._currentMovieService.getCurrentMovie().subscribe(value=>this.currentMovie = value)); // logs undefined
}

Details component html

<div *ngIf="currentMovie">
  {{currentMovie.MovieName}}
</div>

This however doesn't display anything.

sander
  • 1,426
  • 4
  • 19
  • 46

1 Answers1

0

ngOnInit is executed when your component is initialized and your getCurrentMovie() would for sure return undefined because the value is not set yet. Later when you are setting the value your getCurrentMovie method is not invoked either you force invoke it or go for Behavior Subject

I would suggest you go for RxJS BehaviorSubject

You can also use a regular RxJS Subject service, but here’s some advantages of it over subject.

  1. It will always return the current value on subscription - there is no need to call onnext().
  2. It has a getValue() function to extract the last value as raw data.
  3. It ensures that the component always receives the most recent data.
  4. you can get an observable from behavior subject using the asobservable() method on behavior subject.
  5. Refer this for more

your service

import { Injectable } from '@angular/core';
import {Imovie} from './imovie'
import {Observable,of,BehaviorSubject} from 'rxjs';
@Injectable()
export class ShareDataService {

private Movie= new BehaviorSubject<Imovie>(null);
  currentMovie = this.Movie.asObservable();

  constructor() { }

setCurrentMovie(movie:Imovie)
{
  this.Movie.next(movie);
}
}

Component-1

import { Component, Input } from '@angular/core';
import {ShareDataService} from './share-data.service'
import {Imovie} from './imovie'
@Component({
  selector: 'hello',
  template: `<div *ngIf="currentMovie">
  <h2>{{currentMovie.name}}</h2>
   <h2>{{currentMovie.genre}}</h2>
</div>`,
  styles: [`h1 { font-family: Lato; }`] 
})
export class HelloComponent  {
  public currentMovie:Imovie;
 constructor(public service:ShareDataService)
 {
   this.service.currentMovie.subscribe((value)=>{this.currentMovie=value
     console.log(this.currentMovie);
   });
 }

}

Component-2

import { Component } from '@angular/core';
import {ShareDataService} from './share-data.service'
import {Imovie} from './imovie';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public movie:Imovie
  constructor(public service:ShareDataService)
  {

  }
setMovie()
{
this.movie={name:'grudge',genre:'horror'};
this.service.setCurrentMovie(this.movie);
}
}

Component-2 HTML

<button (click)="setMovie()" >SetMovie</button>
<hello></hello>

LIVE DEMO

Vikas
  • 11,859
  • 7
  • 45
  • 69