4

I need pass one http response values to multiple components.

my home component html is

<app-featured></app-featured>
<app-filter></app-filter>
<app-business></app-business>

service file data-video.service

getPosts() {
     return this.http.get('http://grace-controls.com/mind-grid/mind_select.php')
     .map(res=>res.json())
   }

featured.component.ts

featured component is a slick slider

ngOnInit() {
    this.dataServices.getPosts().subscribe((posts)=>{
          this.slides.splice(0, 1);
          for(let i=0; i<posts.length;i++) {
            this.slides.push({img:posts[i].image_url});
          }
        })
}
slides = [{img:''}];

business.component.ts

    ngOnInit() {
    //Here I have to request the same data service method or any common object access values here?
      }

How to get and print the values in business component?. Which is the most preferable way to do? I am beginner in Angular please help me?

Madhuri Patel
  • 1,270
  • 12
  • 24
Rijo
  • 2,963
  • 5
  • 35
  • 62
  • use [rxjs](https://stackoverflow.com/questions/49387889/passing-data-with-subjects-and-proxies/49388249#49388249) – Vikas Apr 24 '18 at 17:54
  • 1
    you can get the data in the feturedComponent just like you did in each of your component or you can just implement it in your HomeComponent and then pass it to the feturedComponent and else by using Inputs, you can check this link for further explanation : https://angular.io/guide/component-interaction – Yassine Ben Hamida Apr 24 '18 at 17:58

3 Answers3

3

i recommand you to create BehaviorSubject to manage locally your Posts collection.

first things is to create Model like this :

/**
 * Strong type each item of your posts api.
 */
export class PostModel {
  id: string;
  title: string;
  descreption: string;
  image_url: string;
  video_id: string;
  country: string;
  language: string;
  company: string;
  date: string;
  clap: string;
  views: string;
  username: string;
}

then you service can looks like this :

@Injectable()
export class PostService {
  // Should be private and expose by magic getter, present bellow.
  private _posts$ : BehaviorSubject<PostModel[]>; 

  constructor(private http: HttpClient) {
    // We init by empty array, this means if you subscribe before ajax answer, you will receive empty array, then be notify imediatly after request is process.
    this._posts$ = new BehaviorSubject([]);
    // Because this data is mandatory, we ask directly from constructor.
    this.loadPost();
  }

  private loadPost() {
    this
    .http
    .get('http://grace-controls.com/mind-grid/mind_select.php')
    .pipe(map(res => (res as PostModel[]))) // We strong type as PostModel array
    .subscribe(posts => this._posts$.next(posts)); // we push data on our internal Observable.
  }
  // Magic getter who return Observable of PostModel array.
  get posts$() : Observable<PostModel[]> {
    return this._posts$.asObservable();
  }
  // magic getter who return Observable of {img:string} array.
  get slides$(): Observable<Array<{img:string}>> {
    return this._posts$.pipe(map(posts => {
        return posts.map(post => {
          return {
            img: post.image_url
          }
        });
    }));
  }
}

Then you can consume your data everywhere on your application, just do :

export class AppComponent implements OnInit{

  constructor(private postService: PostService) { }

  ngOnInit() {
    this.postService.posts$.subscribe(posts => {
      console.log(posts);
    });
    // OR
    this.postService.slides$.subscribe(slides => {
      console.log(slides);
    });
  }
}

Detail : BehaviorSuject have to be init with default value, then when consumer subscribe to it, he will always return last emitted value.

Sample : Online sample Unfortunatly, ajax request throw error from your url because your server is not over https. Anyway this online sample is to have full code ready to check.

__ UPDATE __

I have update my sample, comment HttpCall and replace it by dummy data.

Yanis-git
  • 7,737
  • 3
  • 24
  • 41
2

You should go for the option of using Shared Service across the components. A service in Angular is a singleton, meaning it is managed as a single instance. So if each of the components access the service, they will access the same shared data.

Here is an Example.

Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
1

if you have a data to share to be accessible from all component, you can use ngrx store for state management if you look for the best and clean solution, you can do a call only once and store the result in the store

 you can dispatch your result inside the service

getPosts() {
  return this.http.get('http://grace-controls.com/mind-grid/mind_select.php')
 .map(res=>res.json()).subscribe((results) => {
    this.store.dispatch(new yourActions.GetPosts(result));
 })
}

and you can get your posts list everywhere you need it by calling

this.store.select('postsList');

that return an observable, you can subscribe and get your data

Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52