Vivek Sharma
Vivek Sharma

Reputation: 103

Set nested JSON Response as rowdata to ag-grid in Angular4

I am new to angular and doing a sample project in which I want to show some JSON data in a grid.

I'm using ag-grid for the same. I have the following Json response that I'm getting from a rest API :-

[
 {
  "id": 64,
  "name": "Utopia",
  "language": "English",
  "genres": [
     "Drama",
     "Science-Fiction",
     "Thriller"
  ],
  "status": "Ended",
  "image": {
     "medium": "http://static.tvmaze.com/uploads/images/medium_portrait/0/474.jpg",
     "original": "http://static.tvmaze.com/uploads/images/original_untouched/0/474.jpg"
  }
 },
 {
  "id": 65,
  "name": "Bones",
  "language": "English",
  "genres": [
    "Drama",
    "Crime",
    "Medical"
  ],
  "status": "Ended",
  "image": {
    "medium": "http://static.tvmaze.com/uploads/images/medium_portrait/80/201202.jpg",
    "original": "http://static.tvmaze.com/uploads/images/original_untouched/80/201202.jpg"
   }
 }    
]

I was able to successfully bind the data for the simple keys like id, name, language etc. but when it comes to binding the nested object I'm not able to do it.

If you look at the above json response, The 'image' field is an object. How can I get the value of 'medium' or 'original' key from it and just show the image in my row ?

Some help is appreciated, as this is the point I'm getting stuck at.

Below is my component code :-

shows.component.ts

@Component({
     selector: 'app-shows',
     templateUrl: './shows.component.html',
     styleUrls: ['./shows.component.css']
})
export class ShowsComponent implements OnInit {

  public gridOptions: GridOptions;
  public tvShowsColumnDefs = new ShowColumn;
  public showMetaData: any;

  constructor(private _contentService: ContentService, private _router: Router,
              private _route: ActivatedRoute) {

  // GridOptions Initialized
  this.gridOptions = <GridOptions>{};
  this.gridOptions.columnDefs = this.tvShowsColumnDefs.columnDefs;
}

ngOnInit() {
 // Prepare Grid Row Data
 this.prepareRowData();
}

prepareRowData() {
 // API Call for getting TV-Shows
 this._contentService.getAllShows()
   .subscribe(response => {
     const shows = response;
     console.log('TVShows-API Response ', shows);

    // Setting Grid RowData using api response
    this.gridOptions.api.setRowData(shows);

  });
}

show.columnDef.ts

export class ShowColumn {

public columnDefs = [
    { field: 'id', headerName: '', width: 50 },
    { field: 'image', headerName: '', width: 50, cellRendererFramework: null},
    { field: 'name', headerName: '', width: 250},
    { field: 'language', headerName: 'Language', width: 100},
    { field: 'genres', headerName: 'Genres', width: 250},
    { field: 'status', headerName: 'Status', width: 145 }
];
constructor() { }
}

Upvotes: 2

Views: 6634

Answers (2)

Alexander Zbinden
Alexander Zbinden

Reputation: 2566

The nested properties are accessible by the dot notation (.), e.g.:

{ field: 'image.medium', headerName: '', width: 50}

For the nested arrays, a value-getter will most likely do the job:

function genreValueGetter(params) {
    const arr = params.data.genres as Array<string>;
    return arr.join(', ');
}

{ headerName: 'Genres', valueGetter: genreValueGetter, width: 250},

Upvotes: 3

Arttu
Arttu

Reputation: 371

First let me build classes:

export class myShow {
  image: myImage;
  id: number;
  ...

  constructor(obj: any) {
    this.document = new myImage(obj.image);
    this.id = obj.id;
    ...
  }
}

export class myImage {
  medium: string;
  original: string;

  constructor(obj?: any) {
    if(obj){
      this.medium = obj.medium;
      this.original = obj.original;
    }
  }
}

Then you can use .map operator

  allShows: myShow[] = [];

  prepareRowData(){
    this._contentService.getAllShows().map((shows: myShow[])=> {
        return shows.map((show: myShow)=>{
          return new myShow(show);
        })
    }).subscribe((allShows)=> {
        this.allShows = allShows;
    });
  }

Upvotes: 0

Related Questions