Home > Software engineering >  Angular class does not implement inherited abstract member
Angular class does not implement inherited abstract member

Time:09-27

While working on a program that I am facing an issue with, extending abstract class to shareable angular component

Here is my code:

AgGridDatasource (aggrid.model.ts)

export abstract class AgGridDatasource {

private _gridOptions: GridOptions = DEFAULT_GRID_OPTIONS;
private _gridApi: GridApi;
private _gridColumnApi: ColumnApi;

protected constructor(gridOptions: GridOptions) {
    this._gridOptions = Object.assign({}, this._gridOptions, gridOptions);
}

refreshColumns(): void {
    if (this._gridApi) {
        this._gridApi.setColumnDefs(this.createColumns());
    }
}

abstract createColumns(): AbstractColDef[];

onGridReady(event): void {
    this._gridApi = event.api;
    this._gridColumnApi = event.columnApi;
}

get gridOptions(): GridOptions {
    return this._gridOptions;
}

get gridApi(): GridApi {
    return this._gridApi;
}

get gridColumnApi(): ColumnApi {
    return this._gridColumnApi;
}
}

AgGridComponent

@Component({
  selector: 'ag-grid',
  templateUrl: './ag-grid.component.html',
  styleUrls: ['./ag-grid.component.css']
})
export class AgGridComponent extends AgGridDatasource implements OnInit {
  @Input() columns: AbstractColDef[];
  @Input() datasource: any[];
  modules: Module[] = [ServerSideRowModelModule];
  rowCount?: number;

  protected constructor(gridOptions: GridOptions) {
    super(Object.assign({},{
      rowModelType: 'infinite',
      pagination: false,
      rowSelection: 'none',
      suppressCellSelection: true,
      cacheBlockSize: 100,
     },gridOptions));
  }

  createColumns() {
    console.log(`Getting input columns here`)
    console.log(this.columns)
    return this.columns;
  }



  ngOnInit() {
    this.gridOptions.datasource = this.dataSource;
    this.createColumns();
    this.refreshColumns();
  }

  dataSource: IDatasource = { 
    getRows(params: IGetRowsParams): void {
      setTimeout(() => {
        console.log(`Getting updated input rows here`)
        console.log(this.datasource)
        params.successCallback(this.datasource, -1);
      }, 200);
    }
  }
}

Error Facing (updated):

enter image description here

enter image description here

GITHUB REPO

Scenario:

I just started implementing ag-grid in my application.

I want to configure it programmatically, I want to put all agGrid configuration-related code into a separate abstract class in aggrid.model.ts

I want to use this AgGridComponent in all my application to configure agGrid so that I can manage the agGrid from a single place.

I am writing above code for that but looks like it is not working

CodePudding user response:

You need to provide the implementation of createColumns method in your component. Take createColumns method out of ngOnInit and make it a component instance method:

 protected createColumns() {
      return this.columns;
  }

and then you can call this method from ngOnInit.

One more point you should consider changing is removing the protected modifier from the constructor of AgGridComponent. Since the constructor is protected, Angular will not be able to create an instance of this component. Change this to a public constructor.

CodePudding user response:

I have forked your repo, run it, and ...:

  1. First I've deleted the protected access modifier from AgGridComponent's constructor that was causing: Type 'typeof AgGridComponent' is not assignable to type 'Type<any>'. Cannot assign a 'protected' constructor type to a 'public' constructor type., basically that means that TypeScript has no way of instantiate AgGridComponent if its constructor is protected only usable by itself and its children, so, run it again ...
  2. And then, I realized that you are trying to inject the interface GridOptions as an object dependency into AgGridComponent, and there is the problem I think ...

Because what the Angular injector will be doing is trying to instantiate all the parameters within a component's constructor with the new key word, therefore, because GridOptions is an interface and can't be instantiated, well, then Angular complaints:

No suitable injection token for parameter 'gridOptions' of class 'AgGridComponent'. Consider using the @Inject decorator to specify an injection token.

So, maybe you should create another class maybe decorated with @Injectable(), that implements GridOptions interface and then you would be good to go injecting it into AgGridComponent's contructor.

  • Related