0
votes

found a solution. Actually a good friend helped me out. will post later.

I'm stuck! I can't seem to pass the data to the (grand)child component. I am able to pass the id in routes, and it shows up in the URL, but I can't seem to access any of the data. I'm adding the code below. I've tried everything! is it because the data is passed from the ag-grid model that it can't be passed down to a grandchild? How can I pass the data to my list component? I'm adding the rest of the code to show what I've tried.

original message: I have an ag-grid, and one of the fields is a CellRenderer, which creates a button. I'm trying to pass data into the cellRenderer, so when the user clicks on the button, the data is transferred to that component, and it is then displayed as a list or modal.

my component with the grid ts file:


import { Component, OnInit } from '@angular/core';
import { ReportService } from 'src/app/services/report.service';
import { Report } from 'src/app/models/report';
import { agThemeSgBootstrap } from "@sg-bootstrap/ag-grid";
import { GridOptions } from 'ag-grid-community';
import { DatePipe } from '@angular/common';
import {ViewMoreButtonComponent} from "./view-more-button/view-more-button.component";


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

  apiUrl: any;
  reports : Report[];
  gridOptions: GridOptions;
  dateValue = new Date();
  maxDate = new Date();
  private frameworkComponent;

  columnDefs = [
    {headerName: 'Report Name', field: 'reportName', resizable: true,
      valueGetter: params => { return `${params.data.reportName}.dat` }},
    {headerName: 'Sent to FIS', field: 'sentToFis',resizable: false,
      valueGetter: params => { return params.data.sentToFis === true ? "Yes" : "No"  } },
    {headerName: 'File Size', field: 'contentLength', resizable: true,
      valueGetter: params => { return `${this.formatBytes(params.data.contentLength)}` }},
    {headerName: 'Last Modified', field: 'lastModified', resizable: true,
      valueGetter: params => { return this.datePipe.transform(params.data.lastModified, "yyyy-MM-dd HH:mm:ss") }},
    {headerName: '', field: 'value', resizable: false,
      cellRendererFramework: ViewMoreButtonComponent, width: 180, colId: 'params',
      valueGetter: params => {return `${params.data.id}`}}

  ];

  constructor(private reportService : ReportService, private datePipe: DatePipe) {
    this.frameworkComponent = {
      viewMoreButtonComponent: ViewMoreButtonComponent
    };
  }

  ngOnInit() {
    this.callReportService(new Date())

  }

  reportDateChange(value: Date) {

    let currentValue = this.datePipe.transform(this.dateValue, "yyyyMMdd")
    let newSelectedValue = this.datePipe.transform(value, "yyyyMMdd")
    if (currentValue != newSelectedValue) {
      if (this.gridOptions.api) {
        this.gridOptions.api.showLoadingOverlay();
      }
      this.callReportService(value)
      this.dateValue = value;
    }
  }

  callReportService(value: Date) {
    this.reportService.getReportsForDate(value).subscribe(x=> {
      this.reports = x;
      this.gridOptions.api.sizeColumnsToFit();

    })
  }

  ngAfterContentInit() {
    let agOpt = { ...{
      animateRows: true,
        enableRangeSelection: true,
        defaultColDef: {
          editable: false,
          enableValue: false,
          enableRowGroup: false,
          enablePivot: true,
          filter: true,
          sortable: true
        },
      statusBar: {
        statusPanels: [{
            statusPanel: 'agTotalRowCountComponent',
            align: 'left'
          },
          {
            statusPanel: 'agFilteredRowCountComponent'
          },
          {
            statusPanel: 'agSelectedRowCountComponent'
          },
          {
            statusPanel: 'agAggregationComponent'
          },
        ],
      }
     }, ...agThemeSgBootstrap }
    this.gridOptions  = { ...this.gridOptions, ...agOpt }
  }

  onGridReady(params) {
    params.api.setDomLayout("autoHeight");
    params.api.sizeColumnsToFit();
  }

  onGridSizeChanged(params) {
    params.api.sizeColumnsToFit();
  }

  ngAfterViewInit() {

    this.dateValue = new Date()


  }

  formatBytes(bytes, decimals = 2) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}


}

my button componenet

import {ICellRendererAngularComp} from "@ag-grid-community/angular";
import {Report} from "../../../../models/report";
import {ReportService} from "../../../../services/report.service";

@Component({
  selector: 'app-view-more-button',
  templateUrl: './view-more-button.component.html',
  styleUrls: ['./view-more-button.component.scss']
})
export class ViewMoreButtonComponent implements ICellRendererAngularComp {
  // @Input() id: Report;
  public params: any;
  reports: Report[];


  agInit(params: any) {
    this.params = params;
    console.log(this.data.params.id);

  }

  constructor(reportService: ReportService) { }


  ngOnInit() {

  }

public ViewMore() {
    // this.reportService.
    // this.params.context.componentParent.methodFromParent(`Row:
    // ${this.params.node.rowIndex}, Col: ${this.params.colDef.headerName}`)
  }

  refresh(): boolean {
    return false;
  }

}


my view more button component html file

<app-view-more [params]="params.data" > ></app-view-more>>

<button class="viewMoreButton" mat-stroked-button routerLink="/viewmore/{{params.data.id}}">View More</button>

my grandchild component

import {Component, Input, OnInit} from '@angular/core';
import {Report} from "../../../../../models/report";
import {ReportService} from "../../../../../services/report.service";
import {ViewMoreButtonComponent} from "../view-more-button.component";

@Component({
  selector: 'app-view-more',
  templateUrl: './view-more.component.html',
  styleUrls: ['./view-more.component.scss']
})
export class ViewMoreComponent implements OnInit{
  @Input() params: any[] ;
constructor()   { }

    // getReportDetails() {
    // this.reportService.getParams().subscribe(data => {
    //   this.reportDetail = data;
    // })
    // }
  ngOnInit(): void {
    console.log(this.params[0]);
    // console.log(this.params.reportName);
   }

  }
my parent component

import { Component, OnInit } from '@angular/core';
import { ReportService } from 'src/app/services/report.service';
import { Report } from 'src/app/models/report';
import { agThemeSgBootstrap } from "@sg-bootstrap/ag-grid";
import { GridOptions } from 'ag-grid-community';
import { DatePipe } from '@angular/common';
import {ViewMoreButtonComponent} from "./view-more-button/view-more-button.component";


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

  apiUrl: any;
  reports : Report[];
  gridOptions: GridOptions;
  dateValue = new Date();
  maxDate = new Date();
  private frameworkComponent;

  columnDefs = [
    {headerName: 'Report Name', field: 'reportName', resizable: true,
      valueGetter: params => { return `${params.data.reportName}.dat` }},
    {headerName: 'Sent to FIS', field: 'sentToFis',resizable: false,
      valueGetter: params => { return params.data.sentToXXX === true ? "Yes" : "No"  } },
    {headerName: 'File Size', field: 'contentLength', resizable: true,
      valueGetter: params => { return `${this.formatBytes(params.data.contentLength)}` }},
    {headerName: 'Last Modified', field: 'lastModified', resizable: true,
      valueGetter: params => { return this.datePipe.transform(params.data.lastModified, "yyyy-MM-dd HH:mm:ss") }},
    {headerName: '', field: 'value', resizable: false,
      cellRendererFramework: ViewMoreButtonComponent, width: 180, colId: 'params',
      valueGetter: params => {return `${params.data.id}`}}

  ];

  constructor(private reportService : ReportService, private datePipe: DatePipe) {
    this.frameworkComponent = {
      viewMoreButtonComponent: ViewMoreButtonComponent
    };
  }

  ngOnInit() {
    this.callReportService(new Date())

  }

  reportDateChange(value: Date) {

    let currentValue = this.datePipe.transform(this.dateValue, "yyyyMMdd")
    let newSelectedValue = this.datePipe.transform(value, "yyyyMMdd")
    if (currentValue != newSelectedValue) {
      if (this.gridOptions.api) {
        this.gridOptions.api.showLoadingOverlay();
      }
      this.callReportService(value)
      this.dateValue = value;
    }
  }

  callReportService(value: Date) {
    this.reportService.getReportsForDate(value).subscribe(x=> {
      this.reports = x;
      this.gridOptions.api.sizeColumnsToFit();

    })
  }

  ngAfterContentInit() {
    let agOpt = { ...{
      animateRows: true,
        enableRangeSelection: true,
        defaultColDef: {
          editable: false,
          enableValue: false,
          enableRowGroup: false,
          enablePivot: true,
          filter: true,
          sortable: true
        },
      statusBar: {
        statusPanels: [{
            statusPanel: 'agTotalRowCountComponent',
            align: 'left'
          },
          {
            statusPanel: 'agFilteredRowCountComponent'
          },
          {
            statusPanel: 'agSelectedRowCountComponent'
          },
          {
            statusPanel: 'agAggregationComponent'
          },
        ],
      }
     }, ...agThemeSgBootstrap }
    this.gridOptions  = { ...this.gridOptions, ...agOpt }
  }

  onGridReady(params) {
    params.api.setDomLayout("autoHeight");
    params.api.sizeColumnsToFit();
  }

  onGridSizeChanged(params) {
    params.api.sizeColumnsToFit();
  }

  ngAfterViewInit() {

    this.dateValue = new Date()


  }

  formatBytes(bytes, decimals = 2) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}


}

my report service - (in the middle of the get params function)

import { Injectable } from '@angular/core';
import { Report } from '../models/report';
import { HttpClient } from '@angular/common/http';
import { AppConfig } from '../app.config';
import { DatePipe } from '@angular/common'

@Injectable({
  providedIn: 'root'
})
export class ReportService {

  private apiUrl : string = ""
  private reportEndPoint : string = ""
  report: Report;
  constructor(private httpClient : HttpClient, private appConfig : AppConfig, public datePipe: DatePipe ) {
    this.apiUrl = this.appConfig.settings.apiServer.apiUrl;
    this.reportEndPoint = this.appConfig.settings.apiServer.reportEndPoint;
  }

  getReportsForDate(date : Date) {

     let transfomedDate = this.datePipe.transform(date, "yyyyMMdd")
     return this.httpClient.get<Report[]>(`${this.apiUrl}${this.reportEndPoint}${transfomedDate}` );

  }
  getParams() {
    return this.httpClient.get<Report[]>(`${this.apiUrl}${this.reportEndPoint}`);
    // this.report.reportName;
    // this.report.lastModified;
    // this.report.adlsFullPath;
    // this.report.contentLength;
    // this.report.creationDate;
    // this.report.sentToFis;
  }

 }



1
with this routerLink="/viewmore/{{params.data.id}} your navigating to another route no ?ChiKa LiO
yes. the url displays the correct id, but I don't know how to access the rest of the array. or even this variable. when I do console.log(this.id), or (this.params.id), I get back undefined. I want to mention again that originally I passed the data from another component that uses ag grid, but I seem to be unable to pass it further to the grandchild componentHeidi E
can you create a stackblitz with your sample code?Carlos E
I've never done it but I can sure tryHeidi E
try this way if its a route and not a component onside another onInit(){ this.activatedRoute.queryParams.subscribe(params => { console.log(params['id']); }); }ChiKa LiO

1 Answers

0
votes

my solution: my grandchild component

import {Component, Input, OnInit} from '@angular/core';
import {Report} from "../../../../../models/report";
import {ReportService} from "../../../../../services/report.service";
import {ViewMoreButtonComponent} from "../view-more-button.component";
import {Router} from "@angular/router";

@Component({
  selector: 'app-view-more',
  templateUrl: './view-more.component.html',
  styleUrls: ['./view-more.component.scss']
})
export class ViewMoreComponent implements OnInit{

  public params: any;

  constructor(private router: Router, ) {
    this.params = this.router.getCurrentNavigation().extras.state;

  }

  ngOnInit(): void {
    // console.log(history.state);


    }

  }

my child component


import { Component, OnInit, Input } from '@angular/core';
import {ICellRendererAngularComp} from "@ag-grid-community/angular";
import {Report} from "../../../../models/report";
import {ViewMoreComponent} from "./view-more/view-more.component";
import {Router} from "@angular/router";

@Component({
  selector: 'app-view-more-button',
  templateUrl: './view-more-button.component.html',
  styleUrls: ['./view-more-button.component.scss'],
})
export class ViewMoreButtonComponent implements ICellRendererAngularComp {
  public params: any;
  reports: Report[];


  agInit(params: any) {
    this.params = params;
  }


  constructor(private router: Router) { }


  ngOnInit() {
  }

  refresh(): boolean {
    return true;
  }

  redirect() {
    this.router.navigateByUrl('/viewmore', {state:this.params.data})
  }

}

my child component html file

<button class="viewMoreButton" mat-stroked-button (click)="redirect()">View More</button>