Bryan Bastida
Bryan Bastida

Reputation: 33

Pass JSON file from one component to another using a service using Angular 6

In the displayresults component, I'm trying to pass the response I get from the http.get() to the articleinfo component. I was originally doing this by using queryParams but I need to pass more complex information from my JSON such as other objects and arrays. I'm using the ArticleInformationService to set the response using this.article_info.setJSONData(response); and then I use console.log(this.article_info.getJSONData()); to make sure I'm getting the right data and I am. But now when I go into the articleinfo component and try console.log(article_info.getJSONData()); I get an empty object. My assumption is that article_info inside the articleinfo component doesn't see its value from displayresults because it is a new instance? Am I going about this the right way?

Component 1

import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Router, NavigationExtras } from "@angular/router";
import { ArticleInformationService } from "../article_information/article-information.service";

@Component({
  selector: "app-displayresults",
  templateUrl: "./displayresults.component.html",
  styleUrls: ["./displayresults.component.css"],
  providers: [ArticleInformationService]
})
export class DisplayresultsComponent implements OnInit {
  response: any;
  constructor(
    private http: HttpClient,
    private router: Router,
    private article_info: ArticleInformationService
  ) {}

  ngOnInit() {
    this.search();
  }

  search() {
    var query: string = window.location.search.substring(1).split("=")[1];

    this.http
      .get(
        "http://my.json/_search?q=" +
          query +
          "&size=100"
      )
      .subscribe(response => {
        this.response = response;
            //*******Setting the response to the service atttribute
            this.article_info.setJSONData(response);
            console.log(response);
            console.log(this.article_info.getJSONData());
          });
      }

Component 2

import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ArticleInformationService } from "../article_information/article-information.service";

@Component({
  selector: "app-articleinfo",
  templateUrl: "./articleinfo.component.html",
  styleUrls: ["./articleinfo.component.css"],
  providers: [ArticleInformationService]
})

export class ArticleinfoComponent implements OnInit {
  constructor(article_info: ArticleInformationService) {
    console.log(article_info.getJSONData());
  }
  ngOnInit() {}
}

Service

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

@Injectable({
  providedIn: "root"
})
export class ArticleInformationService {
  jsonData;
  constructor() {
    this.jsonData = {};
  }
  setJSONData(val: object) {
    this.jsonData = val;
  }
  getJSONData() {
    return this.jsonData;
  }
}

Upvotes: 0

Views: 3097

Answers (4)

anubhab
anubhab

Reputation: 760

I think your component2 is getting loaded before service returns response in your component1. You can check https://angular.io/guide/component-interaction for some help

Upvotes: 0

Patrick Kelleter
Patrick Kelleter

Reputation: 2771

By providing your serivce within each of your classes, you are creating two independant instances of your service. The values which are stored in the first version, will not be visible in the second version and vice versa. Provide your service on a higher level instead, for example on the module layer.

Upvotes: 0

Sunil
Sunil

Reputation: 11243

It looks like you have issue with async and sequence of calls. The best would be to use the BehaviorSubject in service class to solve this issue.

The modified code is here -

ArticleInformationService

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

@Injectable({
  providedIn: "root"
})
export class ArticleInformationService {

  private dataSource = new BehaviorSubject({});
  data = this.dataSource.asObservable();

  constructor() {
    this.jsonData = {};
  }
  setJSONData(val: object) {
    this.dataSource.next(val);
  }
  getJSONData() {
    return this.data;
  }
}

ArticleinfoComponent

import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ArticleInformationService } from "../article_information/article-information.service";

@Component({
  selector: "app-articleinfo",
  templateUrl: "./articleinfo.component.html",
  styleUrls: ["./articleinfo.component.css"],
  providers: [ArticleInformationService]
})

export class ArticleinfoComponent implements OnInit {
  constructor(article_info: ArticleInformationService) {
    article_info.getJSONData().subscribe(data=>{
        console.log(data); //<-- data is here
    });
  }
  ngOnInit() {}
}

Note : code was written in stackoverflow editor so there could be typo or syntactical error. Please correct yourself.

Upvotes: 0

Sajeetharan
Sajeetharan

Reputation: 222582

You are resetting the jsonData object in the constructor, which means whenever you instantiate your service, your object will be reset to empty.

Remove setting jsonData to empty inside the constructor, which should solve your issue.

 jsonData = {};
 constructor() {
 }

if you are not doing any refresh via router the above should work. However i would suggest you to use Observable,subject to handle this scenario as mentioned in the answer here.

Upvotes: 1

Related Questions