0

I want to display as group for the crew members by their "Job" from below JSON. for example: Director is one but producers are more than one but want to show like:

producers: producer1, producer2, producer3

Original Music Composer: composer1, composer2

and so on. I want to group them in html view with *ngFor possibly something like

<ul *ngFor="let group of crew">
  <li>{{group.job}}</li>
  <ul>
     <li *ngFor="let crews of group.name">
      {{crews.name}}
     </li>
  </ul>
</ul>

Working demo without grouping: https://stackblitz.com/edit/angular-ttfieu i need to group producer and casting for example in this.

JSON is:

"crew": [
    {
      "credit_id": "56380f0cc3a3681b5c0200be",
      "department": "Writing",
      "gender": 0,
      "id": 7469,
      "job": "Screenplay",
      "name": "Jim Uhls",
      "profile_path": null
    },
    {
      "credit_id": "52fe4250c3a36847f8014a05",
      "department": "Production",
      "gender": 0,
      "id": 7474,
      "job": "Producer",
      "name": "Ross Grayson Bell",
      "profile_path": null
    },
    {
      "credit_id": "52fe4250c3a36847f8014a0b",
      "department": "Production",
      "gender": 0,
      "id": 7475,
      "job": "Producer",
      "name": "Ceán Chaffin",
      "profile_path": null
    },
    {
      "credit_id": "52fe4250c3a36847f8014a11", 
      "department": "Production",
      "gender": 0,
      "id": 1254,
      "job": "Producer",
      "name": "Art Linson",
      "profile_path": "/dEtVivCXxQBtIzmJcUNupT1AB4H.jpg"
    },
    {
      "credit_id": "52fe4250c3a36847f8014a17",
      "department": "Sound",
      "gender": 0,
      "id": 7477,
      "job": "Original Music Composer",
      "name": "John King",
      "profile_path": null
    },
    {
      "credit_id": "52fe4250c3a36847f8014a29",
      "department": "Editing",
      "gender": 0,
      "id": 7480,
      "job": "Editor",
      "name": "James Haygood",
      "profile_path": null
    },
    {
      "credit_id": "52fe4250c3a36847f8014a2f",
      "department": "Production",
      "gender": 0,
      "id": 7481,
      "job": "Casting",
      "name": "Laray Mayfield",
      "profile_path": null
    },

component:

import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { MoviesService } from '../movies.service';

    @Component({
      selector: 'app-crew',
      templateUrl: './crew.component.html',
      styleUrls: ['./crew.component.css']
    })
    export class CrewComponent implements OnInit {
      movie: Object;
      crew: Array<Object>;

      constructor(
        private _moviesServices: MoviesService,
        private router: ActivatedRoute
      ) {
      }
      ngOnInit() {
        this.router.params.subscribe((params) => {
          const id = params['id'];
          this._moviesServices.getMovie(id).subscribe(movie => {
            this.movie = movie;
          });
          this._moviesServices.getMovieCredits(id).subscribe((res: any) => {
            res.crew = res.crew.filter((item) => { return item.job });
            console.log(res)
            this.crew = res.crew;
          });
    })
  }
}

html templare is:

<div class="row mt-3" *ngIf="crew && crew.length > 0">
<div class="col">
    <h3>Crew</h3>
    <div class="row flex-nowrap overflow-auto">
        <div class="col-lg-3 col-4 col-md-3 col-sm-2" *ngFor="let actor of crew">
            <div class="card bg-dark">
                <a routerLink="/crew/{{actor.id}}">
                    <img *ngIf="actor.profile_path" src="https://image.tmdb.org/t/p/w500/{{actor.profile_path}}"
                        alt="{{actor.name}}" class="card-img-top">
                    <img *ngIf="!actor.profile_path" src="../../assets/noimage.png" alt="{{actor.name}}"
                        class="card-img-top">
                    <div class="card-body">
                        <span class="text-white"> {{actor.name}}</span>
                    </div>
                </a>
            </div>
        </div>
    </div>
</div>

thank you in advance

RRPANDEY
  • 235
  • 4
  • 15

1 Answers1

2

Edited to have job value as property key of the grouped object


Try using this and grouping by job:

function groupBy(collection, property) {
   var i = 0, val, index,
        values = [], result = [];
    for (; i < collection.length; i++) {
        val = collection[i][property];
        index = values.indexOf(val);
        if (index > -1)
            result[val].push(collection[i]);
        else {
            values.push(val);
            result[val] = [];
            result[val].push([collection[i]]);
        }
    }
    return result;
}

var obj = groupBy(yourArray, "job");

Refer to this SO post: javascript | Object grouping

Here's a working example on StackBlitz

Jojofoulk
  • 2,127
  • 1
  • 7
  • 25
  • thanks for the response; i want to do this in angular view using ngFor. – RRPANDEY Sep 02 '19 at 09:28
  • You can `*ngFor` the `obj` resulting from the groupBy function – Jojofoulk Sep 02 '19 at 22:51
  • i tried it, is it possible to help here https://stackblitz.com/edit/angular-ttfieu? this display the data as i want but not grouping. – RRPANDEY Sep 02 '19 at 23:06
  • 1
    I added a Stackblitz link to the answer. let me know if that's any good – Jojofoulk Sep 03 '19 at 00:19
  • sorry for bother, please help me to incorporate here on subscribe, this is same as above code in question because i am struggling to incorporate on here: "this._moviesServices.getMovieCredits(id).subscribe((res: any) => { res.crew = res.crew.filter((item) => { return item.job }); // console.log(res) this.crew = res.crew; });" – RRPANDEY Sep 03 '19 at 01:09
  • 1
    Don't know what you're trying to do when filtering `res.crew`. Try to provide a Stackblitz of your actual scenario. Also, this is getting away from your original question, as I believe the answer I gave does answer it. – Jojofoulk Sep 03 '19 at 03:09
  • Yes this answer is perfect and thank you for that!, i am just struggling to replace the hard coded crew [ ] data with your stackblitz solution with the API i have. for example "getMovieCredits" has crews details and just trying to get it done but still working on that if i can. – RRPANDEY Sep 03 '19 at 11:40
  • 1
    Fixed it, Thank you so much and sorry for confusion. This is what i just wanted to do: this.obj = this.groupBy(res.crew, "job"); – RRPANDEY Sep 03 '19 at 12:23
  • 1
    Glad you figured it out yourself :) It's always better when you manage to get it to work by understanding it yourself! – Jojofoulk Sep 03 '19 at 23:27