irossimoline / angular4-material-table

Angular 4 table based on @angular/cdk table structure, to allow row insertion, edition, validation and deletion.
MIT License
55 stars 25 forks source link

Extending TableDataSource #19

Closed mirnpnh closed 5 years ago

mirnpnh commented 6 years ago

Hi, First of all thanks for this great library, i have been using a normal material dataTable which uses an extended DataSource to make http requests (It's actually a socket but let's say http :) ) i have tried to use your component instead but it seems it can't conform exactly like a normal DataSource. I have made the connect and disconnect function with same structure as yours but still TsLint and angular-cli throws error on it.

Here is the error it throws on angular-cli:

Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/angular4-material-table/node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/angular4-material-table/node_modules/rxjs/internal/symbol/observable.d.ts(4,18): error TS2687: All declarations of 'observable' must have identical modifiers.
src/app/_shared/custom-data-source.ts(19,5): error TS2416: Property 'connect' in type 'CustomDataSource' is not assignable to the same property in base type 'TableDataSource<any>'.
  Type '() => Observable<TableElement<any>[]>' is not assignable to type '() => Observable<TableElement<any>[]>'. Two different types with this name exist, but they are unrelated.
    Type 'Observable<TableElement<any>[]>' is not assignable to type 'Observable<TableElement<any>[]>'. Two different types with this name exist, but they are unrelated.
      Types of property 'source' are incompatible.
        Type 'Observable<any>' is not assignable to type 'Observable<any>'. Two different types with this name exist, but they are unrelated.
          Types of property 'operator' are incompatible.
            Type 'Operator<any, any>' is not assignable to type 'Operator<any, any>'. Two different types with this name exist, but they are unrelated.
              Types of property 'call' are incompatible.
                Type '(subscriber: Subscriber<any>, source: any) => TeardownLogic' is not assignable to type '(subscriber: Subscriber<any>, source: any) => TeardownLogic'. Two different types with this name exist, but they are unrelated.
                  Types of parameters 'subscriber' and 'subscriber' are incompatible.
                    Type 'Subscriber<any>' is not assignable to type 'Subscriber<any>'. Two different types with this name exist, but they are unrelated.
                      Property 'isStopped' is protected but type 'Subscriber<T>' is not a class derived from 'Subscriber<T>'.

here is my datasource class extended from your TableDataSource:

export class CustomDataSource implements TableDataSource<any> {

    private rowsObject = new BehaviorSubject<any[]>([]);
    private loadingSubject = new BehaviorSubject<boolean>(false);
    private countSubject = new BehaviorSubject<number>(0);

    public loading$ = this.loadingSubject.asObservable();
    public count$ = this.countSubject.asObservable();

    constructor(private socketSerivce: SocketService) {}

    connect(): Observable<TableElement<any>[]> {
        return this.rowsObject.asObservable();
    }

    disconnect(): void {
        this.rowsObject.complete();
        this.loadingSubject.complete();
    }

    getRows(tableName, filers, sort, page, pageSize, fullTextFields, fullTextValue) {

        this.loadingSubject.next(true);

        this.socketSerivce.getRows(tableName, filers, sort, page, pageSize, fullTextFields, fullTextValue).pipe(
            catchError(() => of([])),
            finalize(() => {})
        )
        .subscribe(lessons => {
            this.loadingSubject.next(false);
            this.rowsObject.next(lessons);
            if (lessons.length > 0) {
                this.countSubject.next(lessons[0].count);
            }
        });
    }
}
fOO223Fr commented 6 years ago

I have a similar problem but I am not using socket service but I am using httpClient! Btw I have a novice question which is are you initiating dataSource=new CustomDataSource()?

irossimoline commented 6 years ago

Hi @Innomalist, It seems that you are not being able to override methods on the base class TableDataSource. The way I see it, you are not trying to implement the TableDataSource but extending it. Am I right?

In case you are extending it, you suppose to be using all the defined behavior from TableDataSource. On the other hand, if you try to implement it (again), you just write your own logic to implement it (CRUD operations and all the stuff).

In the case you are extending it, try to replace implements keyword by extends on your CustomDataSource definition, and use super methods like:

  yourMethod() {
      // call parent object method.
      super.parentClassMethod();
      // do your own logic.
  }

or

// Method with same name in base class, in this case TableDataSource.
  overrideMethod() {
      // You can call parent object method.
      super.overrideMethod();
      // And then you can write your own logic.
     // <Your code comes here>
  }

I suggest you to extend the class, because it's always easier to mantain/update.

Hope it helps, feel free to ping me again if you have questions.

mirnpnh commented 6 years ago

@irossimoline Thanks for your response, The original error had gone away with using exact same versions as the ones this component used in my project too. And also you were right i was trying to extend but instead i was using implementation keyword. My bad it was because i was following the guides on this medium article to make datasource work: https://blog.angular-university.io/angular-material-data-table/ I am still struggling with making crud functions work and no luck yet. Will work more and see how it goes.

Thanks again for your help 👍

amila4d commented 6 years ago

Im facing same issue. still no luck. ERROR in node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'. node_modules/angular4-material-table/node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'. node_modules/angular4-material-table/node_modules/rxjs/internal/symbol/observable.d.ts(4,18): error TS2687: All declarations of 'observable' must have identical modifiers. node_modules/angular4-material-table/src/table-data-source.d.ts(118,5): error TS2416: Property 'connect' in type 'TableDataSource' is not assignable to the same property in base type 'DataSource<TableElement>'. Type '() => Observable<TableElement[]>' is not assignable to type '(collectionViewer: CollectionViewer) => Observable<TableElement[]>'. Type 'Observable<TableElement[]>' is not assignable to type 'Observable<TableElement[]>'. Two different types with this name exist, but they are unrelated. Types of property 'source' are incompatible. Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated. Types of property 'source' are incompatible. Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated. src/app/layout/appraisals/appraisals-list/person-validator.service.ts(7,5): error TS2416: Property 'getRowValidator' in type 'PersonValidatorService' is not assignable to the same property in base type 'ValidatorService'. Type '() => FormGroup' is not assignable to type '() => FormGroup'. Two different types with this name exist, but they are unrelated. Type 'FormGroup' is not assignable to type 'FormGroup'. Two different types with this name exist, but they are unrelated. Types of property 'controls' are incompatible. Type '{ [key: string]: AbstractControl; }' is not assignable to type '{ [key: string]: AbstractControl; }'. Two different types with this name exist, but they are unrelated. Index signatures are incompatible. Type 'AbstractControl' is not assignable to type 'AbstractControl'. Two different types with this name exist, but they are unrelated. Types of property 'validator' are incompatible. Type 'ValidatorFn' is not assignable to type 'ValidatorFn'. Two different types with this name exist, but they are unrelated. Types of parameters 'c' and 'c' are incompatible. Type 'AbstractControl' is not assignable to type 'AbstractControl'. Two different types with this name exist, but they are unrelated. Types of property 'asyncValidator' are incompatible. Type 'AsyncValidatorFn' is not assignable to type 'AsyncValidatorFn'. Two different types with this name exist, but they are unrelated. Type 'Promise | Observable' is not assignable to type 'Promise | Observable'. Two different types with this name exist, but they are unrelated. Type 'Observable' is not assignable to type 'Promise | Observable'. Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated. Types of property 'source' are incompatible. Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated.

ℹ 「wdm」: Failed to compile.

mirnpnh commented 6 years ago

Well i didn't had a luck either, maybe @irossimoline would be kind enough and upload a sample with crud operations requested from a service.

irossimoline commented 6 years ago

Hi @amila4d, @Innomalist,

Could any of you please share the code on stackblitz or other platform so we can iterate over it?

Thank you.

mirnpnh commented 5 years ago

Hi @irossimoline, Thanks for your consideration here is what i got: https://stackblitz.com/edit/angular-e9sk7x. I have managed to extend the TableDataSource object except that i could find a way to convert the the json data to a TableElement object. It seems there was a method called getRowsFromData that was used internally for this purpose but it was marked as private. Also if any improvement or tip comes to your mind please share, I am intending to use this datatable for my next project which heavily uses datatables and any small point might help a lot down the road.

Thanks again,

irossimoline commented 5 years ago

Hi @Innomalist,

Thank you for sharing it and for your feedback. From your comments, I've realized that it would be a good idea to change methods accessibility in order to facilitate extensions on the package, so I've changed those private methods to protected. Now you can use them to extend the table! 😄 I've published a new version (0.6.8) with the changes. Also, checked the code on Stackblitz, and made some changes to make it work with the new package versión. Please check it at: https://stackblitz.com/edit/angular-e9sk7x

It is a very good idea to extend the package to make it work automatically with an endpoint, but always remember to make it open for all your needs. An improvement you could do is to make the table receive an extra configuration with the url you want to check, so you can use it everywhere you need to connect remote data with tables.

Hope it helps, feel free to ping me again if you have questions, and keep up the good work!! 👍

irossimoline commented 5 years ago

Hi @Innomalist, have you any update on this?

mirnpnh commented 5 years ago

Hello @irossimoline, Thanks again for your help and consideration, You were great and yes i tried everything today and they seemed good. I have one problem with createNew function that even though it's calling correctly to function inside TableDataSource and pushing new item to the list but it doesn't shows the newly added row, I think i will be able to go around it and have adding row in another way so it's not important, I just have one suggestion that if you'd like to add in next releases. The confirmEdit, delete and confirmCreate have a boolean value return which i am not sure of the effect of it's return value but requests done in this function are usually http requests or other async operations like promises or observables, So having this implemented in async manner so the value returned by these functions to be like Promise<boolean> and the boolean result would cause the row edit to be saved or reverted back to previous state would lead to a much cleaner code. Thanks again :)