4

Using Angular 2, I receive JSON data from a service. Something like this:

{
    "customerName": "foo",
    "customerAddress": "123 Somewhere",
    "products": 
    [
        {
            "productName": "bar",
            "productNumber": 123 
        },
        {
            "productName": "baz",
            "productNumber": 456             
        }
    ]
}

In my component I subscribe to the service to get populate customerData.

private _getData() {
    this._myService
        .getData()
        .subscribe(
            customerData => this.customerData = customerData,
            error => this.errorMessage = error
        );
}

This code works correctly.

In the JSON dump there are two data "groupings", the customer data and the product data, the latter in the array. Ideally I'd like to populate the product data separately. Something like this:

        .subscribe(
            customerData => this.customerData = customerData,
            productData => this.productData = customerData.products
            error => this.errorMessage = error
        );

Is this possible, and if so how would I code the subscription?

ebakunin
  • 3,621
  • 7
  • 30
  • 49

3 Answers3

9

You could write subscribe like

    subscribe(
        customerData => 
        { 
         this.customerData = customerData;
         this.productData =customerData.products;
        },
        error => this.errorMessage = error
    );

Or

   subscribe(
        function(customerData)
        { 
         this.customerData = customerData;
         this.productData =customerData.products;
        },
        error => this.errorMessage = error
    );
Antonio
  • 644
  • 5
  • 17
2

You could split up the data in the subscribe() callback:

private _getData() {
   this.customerData = {};
   this.productData  = {};
   this._myService.getData().subscribe(data => {
      Object.keys(data).forEach(key => {
         if(key.startsWith("customer")) {
            this.customerData[key] = data[key];
         } else {
            this.productData[key]  = data[key];
         }
      });
   });
 }

Note that startsWith() is not supported on IE.


Or you could split up the data inside the service. One way to do that would be as follows:

  • in the service, create two Subjects in your service and two observables from those Subjects, e.g., custData$, prodData$
  • in the service, subscribe() to your http.get() observable, and split up the data as shown above
  • call this.custData$.next(this.customerData) and this.prodData$.next(this.productionData) to emit the data
  • have your component subscribe to custData$, prodData$
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
0

I have an observable for each data that I want to separate, something like this :

Service

private getDataFromHttp() {
    return this._http
        .get(this.url)
        .map(res => res.json())
        .do(data => {
            console.log(data);
        });
}
public getCustomerData() {
    getDataFromHttp()
        .map(res => res.customerData)
}
public getProductData () {
    getDataFromHttp()
        .map(res => res.productData)
}

Component

private _getData() {
    this._myService
        .getCustomerData()
        .subscribe(
            customerData => this.customerData = customerData,
            error => this.errorMessage = error
        );
}

private _getData() {
    this._myService
        .getProductData()
        .subscribe(
            productData => this.productData = productData,
            error => this.errorMessage = error
        );
}  

This example will make a http request for every function call, HERE is another post of how I cache the observable to not request data from the server every time :caching results with angular2 http service

Community
  • 1
  • 1
Tiberiu Popescu
  • 4,486
  • 2
  • 26
  • 38