3

I am getting an [object Object] while using Observable map in angular 2.

Here is the response object from the API service.

{
  "isSuccess": true,
  "message": "Connection Successfull",
  "data": [
    {
      "marketId": 1,
      "city": "san",
      "cityF": "san",
      "name": null,
      "nameF": "hello",
      "sortOrder": 1,
      "isActive": true
    },
    {
      "marketId": 2,
      "city": "san",
      "cityF": "san",
      "name": null,
      "nameF": "hello",
      "sortOrder": 1,
      "isActive": true
    },
    {
      "marketId": 3,
      "city": "san",
      "cityF": "san",
      "name": null,
      "nameF": "hello",
      "sortOrder": 1,
      "isActive": true
    },
    {
      "marketId": 4,
      "city": "san",
      "cityF": "san",
      "name": null,
      "nameF": "hello",
      "sortOrder": 1,
      "isActive": true
    }
  ],
  "exceptionErrorMessage": null,
  "errorCode": 0,
  "successMessage": null
}

Here is the model I have created to map with the response.

export class MarketViewModel 
{
public isSuccess: boolean;
public message : string;
public successMessage : string;
public exceptionErrorMessage : string;
public errorCode: number;
public data: MarketListObject[];

}
export class MarketListObject 
{
    public marketId : number;
    public city: string;
    public cityF : string;
    public name : string;
    public nameF : string;
    public sortOrder : number;
    public isActive : boolean; 
}

Service class to call the http and map the response.

import { Headers, RequestOptions } from '@angular/http';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { MarketViewModel} from "../ViewModel/Market.ViewModel";
import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class DashBoardService {
    private MarketUrl = "DashBoard/GetMarketList";
    private ResponseData: any;
    constructor(private http: Http, private router: Router, private  marketModel : MarketViewModel) {}

    public GetMarketListCall() :Observable<MarketViewModel> {
         return this.http.get(this.MarketUrl).map(this.extractData)
                    .catch(this.handleError);
    } 
private extractData(res: Response) {
    let body = res.json();
        console.log("Body Data = "+body.data);
    return body.data || { };
  }

Here is the Component.ts which is calling Service.ts

import { Component } from '@angular/core';
import { MarketViewModel} from "../ViewModel/Market.ViewModel";
import { DashBoardService} from "../Service/DashBoard.Service";
import { Observable } from 'rxjs/Observable';

 @Component({
     selector: 'Market-app',
    templateUrl: 'DashBoard/MarketListView',
    providers: [DashBoardService, MarketViewModel]
 })

export class MarketComponent {
  constructor(private DashBoardservice: DashBoardService, private  marketModel : MarketViewModel) {
   }

ngOnInit() {
        this.DashBoardservice.GetMarketListCall().subscribe(
                               data => {this.marketModel = data;
                                    console.log("this"+this.marketModel); }, 
                                err => {console.log(err);});
}
}

When I see to the console I am getting [object Object] response. Where is the mistake I am not able to figure it out

1
  • You are appending the objects to a string here- console.log("Body Data = "+body.data); ... Try this instead - console.log("Body Data = ", body.data); . And the same thing at "this"+this.marketModel) Commented Jan 13, 2017 at 8:14

2 Answers 2

4

You have a problem with your extractData, you want the response as it is, to match your MarketViewModel, so you need to remove the data from that method and also to return an empty object if there is no response:

private extractData(res: Response) {
  let body = res.json();
  return body || {};
}

Some pointers:

  • In your Service and MarketComponent you do not need to inject the MarketViewModel in your constructor.
  • You need to declare a variable marketModel in your component, to be able to use this.marketModel.
  • In component you have declared method ngOnInit, but not implemented it in your component

When testing your app it worked:

getMarketListCall(): Observable<MarketViewModel>{
    return this.http.get('theUrl')
        .map(res => res.json()) // or use the 'extractData'
        // .catch(this.handleError);
}

Your component:

marketmodel: MarketViewModel

ngOnInit() {
    this.DashBoarservice.GetMarketListCall()
       .subscribe(data => {
          this.marketModel = data;
        },
        err => { console.log(err); 
    });
}

Your view, you should wrap your html in an if-statement, since your data gets retrieved asynchronously:

e.g:

<div *ngIf="marketModel"> <!-- Here! -->
  <h2>MarketModel Message: {{marketModel.message}}</h2>
  <div *ngFor="let data of marketModel.data">Id: {{data.marketId}} </div>
</div><br>

We need to remember though this code works wonderfully, we have not actually casted the response to be of instances of your classes. If you wish to do that, I suggest the following link with some great answers :) How do I cast a JSON object to a typescript class

Sign up to request clarification or add additional context in comments.

4 Comments

I am getting an error as ... Can't resolve all parameters for MarketViewModel: (?, ?, ?, ?, ?, ?).
Hmmm, strange, worked perfectly for me. At what point do you get the error?
Don't use classes to define these types. use interfaces.
3

You have to change your DashBoardService as below as you are have to return MarketListObject array as observable not MarketViewModel :

@Injectable()
export class DashBoardService {
  private MarketUrl = "DashBoard/GetMarketList";
  private ResponseData: any;

  constructor(private http: Http, private router: Router, private  marketModel : MarketViewModel) {}

  public GetMarketListCall() :Observable<MarketListObject[]> {
     return this.http.get(this.MarketUrl).map(this.extractData)
                .catch(this.handleError);
  } 

  private extractData(res: Response) {
    let body = res.json();
    console.log("Body Data = "+body.data);
    return body.data || [];
  }
}

Also there is no need to pass MarketViewModel as providers inside MarketComponent so remove MarketViewModel from MarketComponent providers list and change your component as below .

import { Component } from '@angular/core';
import { DashBoardService} from "../Service/DashBoard.Service";
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'Market-app',
  templateUrl: 'DashBoard/MarketListView',
  providers: [DashBoardService]
})
export class MarketComponent {

  public marketList: any[];

  constructor(private dashBoardservice: DashBoardService) {
  }

  ngOnInit() {
    this.dashBoardservice.GetMarketListCall().subscribe((data) => { 
      this.marketList = data;
      console.log("this" + this.marketList);
    },(err) => {
      console.log(err);
    });
  }
}

6 Comments

It didn't work for me .. I am getting [object Object],[object Object],[object Object],[object Object]
Inside extractData function or inside ngOnInit of MarketComponent ? also check by removing :Observable<MarketListObject[]> from GetMarketListCall functions return type.
If I use subscribe in service then everything works fine. When I used map I am getting a object. Yeah I check in ngOnInit. I am still getting object
i have updated component in my answer. inside component marketList variable should be array of MarketListObject like public marketList: MarketListObject[] so import it and change it if it required otherwise any[] will also work.
Can you please let me know how to map with the class as the response from the web api class.I dont want direct array. I want to map with the object
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.