0

I am building an Angular 7 app. In this app I am fetching JSON data from the server that I then want to group by a specific key. I managed to do this but I then no longer have an array but some kind of an object.

Starting JSON data

[{
    "id": 67,
    "survey_id": 26,
    "question_id": 63,
    "user_id": 35,
    "privacy": null,
    "score": null,
    "comment": "A nice little comment",
    "binary": null,
    "reasons": null,
    "preferences": "{}",
    "created_at_date": "2019-09-18",
    "created_at_time": "19:53",
    "user": {
        "id": 35,
        "fullname": "Michael Palin"
    },
    "can_manage": true
},
{
    "id": 68,
    "survey_id": 26,
    "question_id": 64,
    "user_id": 4,
    "privacy": null,
    "score": null,
    "comment": "Another little comment",
    "binary": null,
    "reasons": null,
    "preferences": "{}",
    "created_at_date": "2019-09-18",
    "created_at_time": "19:53",
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
},
{
    "id": 69,
    "survey_id": 26,
    "question_id": 65,
    "user_id": 4,
    "privacy": null,
    "score": null,
    "comment": "Some more comments",
    "binary": null,
    "reasons": null,
    "preferences": "{}",
    "created_at_date": "2019-09-18",
    "created_at_time": "19:53",
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
},
{
    "id": 70,
    "survey_id": 26,
    "question_id": 66,
    "user_id": 4,
    "privacy": null,
    "score": 5,
    "comment": null,
    "binary": null,
    "reasons": null,
    "preferences": "{}",
    "created_at_date": "2019-09-18",
    "created_at_time": "19:53",
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
}

]

This is my grouping code

setupStats() {
    const groupBy = (array, key) => {
      return array.reduce((result, currentValue) => {
        (result[currentValue[key]] = result[currentValue[key]] || []).push(
          currentValue
        );
        return result;
      }, {});
    };
    const grouped = groupBy(this.collection, 'user_id');
    console.log(grouped);
  }

This is the output

{4: Array(3), 35: Array(1)}

The 4 and 35 is the user_ids. I would like them to get parts of an array so I can loop them, that I cannot do now.

3
  • how should the result look like? Commented Sep 18, 2019 at 20:42
  • You can find it on "This is the output" Commented Sep 18, 2019 at 20:44
  • i have seen it, but what do you want? Commented Sep 18, 2019 at 20:45

2 Answers 2

1

If you're looking to bind your grouped data to the template with an *ngFor directive, you can leverage the keyvalue pipe to iterate over your grouping object:

<div *ngFor="let group of groupedItems | keyvalue">
  <strong>{{ group.key }} {{ group.value.length }} items</strong>
  <div *ngFor="let item of group.value">
    {{item.id}} {{item.comment}}
  </div>
</div>

You can read about the keyvalue pipe here.

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

2 Comments

That worked perfectly! I did not know about keyvalue. Thank you!
Great. Glad it helped.
1

You can use a simple loop to do this grouping, something like this:

const arr = [{
    "id": 67,
    "survey_id": 26,
    "comment": "A nice little comment",
    "user": {
        "id": 35,
        "fullname": "Michael Palin"
    },
    "can_manage": true
},
{
    "id": 68,
    "survey_id": 26,
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
},
{
    "id": 69,
    "survey_id": 26,
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
},
{
    "id": 70,
    "survey_id": 26,
    "user": {
        "id": 4,
        "fullname": "Roland Smacker"
    },
    "can_manage": true
}];

const map = {};

for(const item of arr) {
  const id = item.user.id;
  if(!map[id]) {
    map[id] = [];
  }
  
  map[id].push(item);
}

// Access specific group by id.
// console.log(map['4']);

// Loops over all the groups.
for(const [id, groupArr] of Object.entries(map)) {
  console.log('id: ' + id);
  console.log('associated array: ', groupArr);
}

3 Comments

I need to group on the key (user_id) not a specific ID. How can I modify this code to work with that?
this is how grouping looks like. You can still loop over the map if you want, why you say you can't ? What exactly do you want to achieve?
@MarkDenn please check now my answer, I have updated the code to loop over all the groups.

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.