1

I'm getting an array of objects as a HTTP response and I'm trying to group them by a value in the object. As an example let's say I get the following:

[
{player: 'Jordy Nelson', team: 'Packers'},
{player: 'Aaron Rogers', team: 'Packers'},
{player: 'Dak Prescott', team: 'Cowboys'},
{player: 'Ezekiel Elliot', team: 'Cowboys'},
{player: 'Joe Flacco', team: 'Ravens'},
{player: 'Julio Jones', team: 'Falcons'},
]

I'm trying to take that response and convert it to an array of objects, containing an array of objects

[
{'Packers': 
  [
    {player: 'Jordy Nelson', team: 'Packers'}, 
    {player: 'Aaron Rogers', team: 'Packers'}
  ]
},
{'Cowboys': 
  [
    {player: 'Dak Prescott', team: 'Cowboys'},
    {player: 'Ezekiel Elliot', team: 'Cowboys'}
  ]
},
{'Ravens':
  [
    {player: 'Joe Flacco', team: 'Ravens'}
  ]
},
{'Falcons':
  [
    {player: 'Julio Jones', team: 'Falcons'}
  ]
}
]

I've tried using groupBy in the way mentioned in other SO posts

return this.http
  .get(`${environment.baseUrl}/players`, options)
  .map(res => res.json())
  .groupBy(
    res => res.team,
    res => res // I've also tried removing this, filtering and flatmap
  )
  .flatMap(teams => {return teams})

But it returns a 2d array where axis 1 is a single object like so:

[
  [
    {'Packers': {player: 'Jordy Nelson', team: 'Packers'}
  ],
  [
    {'Packers': {player: 'Aaron Rogers', team: 'Packers'}
  ]
]

What do I need I to do format my response properly? Thanks!

With a lot of help from @coderek answer I wrote a little function that can dynamically regroup HTTP responses (so you don't hit the API for each time you'd like to groupBy on a different key). Here's the post on reddit if anyone else comes across this problem https://www.reddit.com/r/Angular2/comments/629nfg/how_to_dynamically_group_a_http_response/

Obj3ctiv3_C_88
  • 1,478
  • 1
  • 17
  • 29
  • This is a duplicate question: check out http://stackoverflow.com/questions/14800862/how-can-i-group-data-with-an-angular-filter – Arvindsinc2 Mar 29 '17 at 14:38
  • @Arvindsinc2 That's AngularJS, not Angular. Also, that is in the template, I'm trying to do this within the component. I saw that there is underscoreJS but I'd rather only use RXJS since it seems like it's possible (I'm just not doing it right) – Obj3ctiv3_C_88 Mar 29 '17 at 14:42

1 Answers1

3

GroupBy works on streams. So First, you need to convert your source to stream first instead of array. Second, you get group results by stream, that's how observable works.

this.http.get('api/players')
  .mergeMap(a=> a.json().data)
  .groupBy(
      a=>a.team,
      a=>a,
  )
  .subscribe(
    (obs) =>{
        obs.subscribe((a)=>{
            console.log(a, obs.key);
        });
    }
  )
}
coderek
  • 1,860
  • 14
  • 20
  • Thanks! A note for other people, depending on response (or maybe it's because I have a different Angular build) the mergeMap may be (a => a.json()) instead of (a => a.json().data). – Obj3ctiv3_C_88 Mar 29 '17 at 18:50