0

I am working with ionic 2 and angular 2. Right now I have two observables that contain object arrays and are being passed to my template to be displayed:

users: Observable<User[]>; scores: Observable<Score[]>;

In my template I currently have to display them separately:

<ion-card *ngFor="let score of scores | async" >
  <ion-item text-wrap>{{ score.total }} </ion-item>
</ion-card>

<ion-card *ngFor="let user of users | async" (click)="goToPlayer(user, league)">
<ion-item text-wrap>{{ user.id }}</ion-item>
</ion-card>

However, I would like to be able to display these values together, user.id and score.total, on the same line. Currently it displays all scores and then all user ids. The Observable arrays always contain the same number of items.

The models for User and Score are:

export interface User {
id?: string,
email?: string,
leagues?: any[],
dateCreated: Date
};

export interface Score {
scores: any[],
total: number
};

Using sample zip code from Aravind's answer:

this.users = this.userData.loadUsers(this.league.id);
this.scores = this.leagueData.loadPlaylistScores(this.league.id);

Observable
.zip(this.users,
     this.scores,
     (id: number, total: number) => ({ id, total }))
.subscribe(x => console.log(x));

prints out three objects to the console, which is the correct number of objects. However each is Object {id: Array[0], total: Array[0]}

jstrout
  • 1
  • 2
  • update your post with relevant sample json and Observable code – Aravind Feb 20 '17 at 19:15
  • Sounds more like a problem with how zip was used than anything since zip is made for this case. – Namirna Feb 20 '17 at 19:16
  • @Namirna zip is used on properties inside an Observable, so the OP is looking for this format **{ id : 1, score : 200 }** to extract in this format json response is mandatory to map properties accordingly. Have a look at my answer below – Aravind Feb 20 '17 at 19:24
  • @Aravind well yeah, I was thinking of zip in RxJS like you answered, not the "normal" zip for arrays in JS, but reading I see I missed mentioning that in that in my comment. – Namirna Feb 20 '17 at 19:41
  • @Namirna , its fine. all are learning. :) – Aravind Feb 20 '17 at 20:33

1 Answers1

1

Guess the below code helps you

Observable
    .zip(users
         scores,
         (id: number, total: number) => ({ id, total }))
    .subscribe(x => console.log(x));

Note: If this does not work, required your sample json to look for specific properties. Based on which I can update

Aravind
  • 40,391
  • 16
  • 91
  • 110
  • This returns the error: Cannot read property 'Symbol(Symbol.iterator)' of undefined. I updated question with the models. – jstrout Feb 20 '17 at 19:41
  • The data is being pulled from a Firebase db and then mapped through a series of functions to these models, so I'm not sure how to show you the json. I found the bug that was producing the 'Symbol(Symbol.iterator) error, as I was occasionally passing in the Observables before they were filled. Now the above code produces a Observable<{ id: string; total: number; }> which is not iterable and produces error: "Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays." when trying to display in template. – jstrout Feb 20 '17 at 20:21
  • Update the code which you used to zip with my answer as a reference. Also where are you getting the users, scores from? – Aravind Feb 20 '17 at 20:29
  • I updated question with results from using your answer. I am getting the users and scores from functions that pull data from firebase and then map the data to the models. I think it is way too much to copy here. The users and scores are both displaying correctly on their own. – jstrout Feb 20 '17 at 21:01