9

I am trying out Angular 2's http GET to retrieve a list of top articles on HackerNews and after which I will retrieve their respective details in a nested observable.

I encounter this error when I try to loop and display the data in my HTML.

Cannot find a differ supporting object '[object Object]'

Cannot find a differ supporting object '[object Object]'

Also, I am guessing there should be a better way to do this, any pointer?

getTopPost() {
    this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
      .map(res => res.json())
      .subscribe(
        data => { 
                    data.map(function(postId){
                            let storyUrl = "https://hacker-news.firebaseio.com/v0/item/"+ postId +".json";
                            that.http.get(storyUrl)
                                .map(res => res.json())
                                .subscribe(data => that.hnData = data, 
                                           err => that.logError(err),
                                           () => console.log(that.hnData));

                        });

                },
        err => this.logError(err);
      );

  }

HTML

<ion-item *ngFor="#item of hnData">
        {{item.title}}
</ion-item> 

2 Answers 2

18

I think you can rewrite it in a more Rx-ish way like this:

getTopPost() {
  return http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    .map(res => res.json())
    .mergeMap(list => Observable.fromArray(list))
    .mergeMap(postId => http.get("https://hacker-news.firebaseio.com/v0/item/"+ postId +".json"))
    .map(res => res.json())
}
Sign up to request clarification or add additional context in comments.

Comments

5

I don't think it's a good practice to nest observable xhr calls... but I'm not a expert about it and can't tell you why you got this exception (maybe about this that var..).

But I have a different approach to show you:

A first component <top-stories> load the id list and then generate others component <top-story> for each one:

@Component({
  selector: 'top-stories',
  providers: [],
  template: '
    <div>
      <h2>Hacker news top stories:</h2>
      <ul>
        <li top-story *ngFor="#story; #i = index of list | async" [num]="i+1" [id]="story"></li>
      </ul>
    </div>
  ',
  directives: [TopStory]
})
export class TopStories {
  list: Observable<Array<number>>;

  constructor(private http: Http) {
    this.list = this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    .map(res => res.json())
    .map(list => list.slice(0, 30));
  }
}

The component <top-story> load itself post details and show it:

@Component({
  selector: '[top-story]',
  providers: [],
  template: `
    <div>
      <a *ngIf="item" [href]="item?.url">{{ num + ': ' + item?.title }}</a>
      <span *ngIf="!item">loading...</span>
    </div>
  `,
  directives: []
})
export class TopStory implements OnInit, OnDestroy {
  @Input() num: Number;
  @Input() id: Number;

  sub: any;
  item: object;

  constructor(private http: Http) {}

  ngOnInit() {
    this.sub = this.http.get('https://hacker-news.firebaseio.com/v0/item/' + this.id + '.json')
    .map(res => res.json())
    .subscribe(item => this.item = item);
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}

You can play with it in this plunker: http://plnkr.co/edit/BRMlyD?p=preview

2 Comments

but why isn't a good practice to nested them? I have a problem because I'm nesting to http.get that return two observable, I'm trying it to have something like promise (resolve first call then do the second) but I get some undefined parameters like I'm in another scope.
I don't really think it is bad to nest observable xhr calls but what is bad is to nest subscriptions (subscribe to an observable inside another observable subscription). You have to use operators like flatMap, concatMap,.. and subscribe to it only one time.

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.