We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

a REAL Custom Adapter / DataManager for CUSTOM Data (GraphQL)

Hello,

I´ve been struggling for days now.
It is not possible to create a real custom adaptor.
I have look up every forum entry and google result.

I CAN create a Service that extends BehaviorSubject<DataStateChangeEventArgsbut that is not a Adapter I can use for eg. setting the DataSource for Foreign Key Column.
The CustomAdapter doesnt work with promises so i can not just create my own Adapter that extends you Adaptor class.
I do not want to make HTTP calls in that class. I have seperate GraphQL classes and implementations for that.

I please need urgent help since this is a total show stopper regarding syncfusion for us.

Thanks

9 Replies

TS Thavasianand Sankaranarayanan Syncfusion Team December 12, 2019 01:01 PM UTC

Hi Dennes, 

Thanks for contacting Syncfusion support. 

Currently, we don’t have GraphQL support in data manager. We have already considered “GraphQL support for Essential JS 2 DataManager”as feature and added to our feature request list. It will be implemented in any of any upcoming release. You can track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.   


Regards, 
Thavasianand S. 



DE Dennes December 12, 2019 01:06 PM UTC

Ok, but dont get me wrong. I dont want / need a GraphQL Adapter, since i get my data already.
I want to have a Custom Adapter that I can MANUALLY feed all the data.

Just like I can have the extends BehaviorSubject<DataStateChangeEventArgs> Service - but as an adapter.

I hope you understand me, or I dont understand the idea of a SyncFusion Custom Adaptor.

Thanks!




TS Thavasianand Sankaranarayanan Syncfusion Team December 13, 2019 12:21 PM UTC

Hi Dennes, 

Thanks for your update. 

You can create your own adaptor by extending the build-in adaptor. Here, we have extended the UrlAdaptor  and overridden the default processQuery and ProcessResponse method of urlAdaptor. You can also customize the method based on your requirement.  

In the below code example, we have formed the GraphQL query based on the grid actions(query) in processQuery method and return the response as result and count pair object in processResponse method. 

import { Query, DataManager, UrlAdaptor } from "@syncfusion/ej2-data"; 
 
/** 
* GraphQL Adaptor with Essentail JS2 Grid 
*/ 
 
export class CustomGraphQLAdaptor extends UrlAdaptor { 
    public opt: IGraphQLAdaptorOptions; 
    public schema: { result: string, count: string }; 
    public query: string; 
    public getVariables: Function; 
    public getQuery: Function; 
 
    constructor(options: IGraphQLAdaptorOptions) { 
        super(); 
        this.opt = options; 
        this.schema = this.opt.response; 
        this.query = this.opt.query; 
        // tslint:disable-next-line:no-empty 
        this.getVariables = () => { }; 
        this.getQuery = () => this.query; 
    } 
 
    processQuery(datamanager: DataManager, query: Query) { 
        var result = super.processQuery.apply(this, arguments); 
        var tmp = JSON.parse(result.data); 
        var vars = this.getVariables() || {}; 
        vars['datamanager'] = tmp; 
        var data = JSON.stringify({ 
            query: this.getQuery(), 
            variables: vars 
        }); 
        result.data = data; 
        return result; // form query based on your need 
    } 
    processResponse(data: any, context: any, query: any) { 
        return data.data.orders;  // should return result and count  
    } 
 
    generateData(inserted: { data: string }, action: string) { 
        let parsed = JSON.parse(inserted.data); 
        inserted.data = JSON.stringify({ 
            query: this.opt.getMutation(action), 
            variables: parsed 
        }); 
        return inserted; 
    } 
} 
 
let data: Object = new DataManager({ 
    url: 'http://localhost:4000/graphql', 
    adaptor: new CustomGraphQLAdaptor({ 
        response: { 
            result: 'orders', 
            count: 'count' 
        }, 
        query: `query Order($datamanager: DataManager) {  // initial loading 
                orders(datamanager: $datamanager) { 
                    result { // column names are defined 
                        CustomerID, 
                        ShipName, 
                        Freight 
                    }, 
                    count 
                } 
            }` 
    }) 
}); 
. . . . .  
export interface IGraphQLAdaptorOptions { 
    response: { result: string, count: string }; 
    query: string; 
    getQuery?: () => string; 
    getVariables?: () => Object; 
    getMutation?: (action: string) => string; 
} 


 

[Return response as result and count object as follows in processReponse method ] 
 



Regards, 
Thavasianand S. 



DE Dennes December 16, 2019 09:10 AM UTC

Thank you very much for your hard work, I really appreciate it.
But again ... this makes the Adapter it self do the GraphQL Http / Url calls .. and that is what we do not want!

simply put:

let me get my own Data (async) in processQuery and return whatever I want, without having to rely on the built in web call.

would that be possible?

Thanks!




TS Thavasianand Sankaranarayanan Syncfusion Team December 17, 2019 01:31 PM UTC

Hi Dennes, 

Thanks for your update. 

By default, while using custom adaptor then we can able to customize the query, url etc., but when we try to prevent the HTTP(web call) request it does not work as expected. As per your previous update, we suspect that you want to use foreign key column in grid with observable, if so then we suggest you to use the below way to bind foreign key data source for columns in Grid. 

Please refer the below code example for more information. 

<ejs-grid #grid [dataSource]='data | async' allowPaging='true' [editSettings]='editSettings' allowGrouping='true' 
  allowReordering='true' (actionFailure)="actionComplete($event)" [toolbar]='toolbar' (dataStateChange)='dataStateChange($event)'> 
  <e-columns> 
    <e-column field='id' headerText='Customer ID' width='120' textAlign='Right' isPrimaryKey='true'></e-column> 
    <e-column field="name" headerText="City" foreignKeyField="name" foreignKeyValue="ShipCity" [dataSource]='colData' 
      width="150"></e-column> 
  </e-columns> 
</ejs-grid> 
 
 
public ngOnInit(): void { 
        . . . . . 
        this.crudService.execute(state); 
        const fData: Object[] = [ 
            { id: 1, name: 'HANAR', ShipCity: 'Germany' }, 
            { id: 2, name: 'VINER', ShipCity: 'Berlin' }, 
            . . . . . 
            ]  // you can get the foreign key data and assign to data manager 
        this.colData = new DataManager({ 
            json: fData 
        }); 
    } 


If we misunderstood or the above does not meet your query then share more details about your requirement(Share the problem that you are facing and share the sample or code example and share more info about requirement / scenario & package version details) that will helpful for us to analyze further and to provide a better solution as soon as possible.  

Regards, 
Thavasianand S.  



DE Dennes December 18, 2019 03:16 PM UTC

Thanks for the Update!

Yes we are getting into the right direction!

But how can I have a remote  "foreign key data source" ?

Because I cannot load 10000 Json objects just for the lookup.

So again, I need a DataManager where I can control the return value without SyncFusion having any logic.

I was using this in the DevExtreme Lib:


the customStore has this function where I return a Promise:
load: function (loadOptions: any) 

Is it understandable?

Thanks!




TS Thavasianand Sankaranarayanan Syncfusion Team December 19, 2019 12:47 PM UTC

Hi Dennes, 

Thanks for your update. 

As per your suggestion, we have created a sample and bind remote data for foreign key column with custom data binding. Please refer the below code example and sample for more information. 

<ejs-grid #Grid [dataSource]='data | async' allowPaging= 'true' [pageSettings]='pageOptions' allowSorting= 'true' allowGrouping= 'true' (dataStateChange)= 'dataStateChange($event)' (actionFailure)='fail($event)'> 
  <e-columns> 
      . . . . . 
      <e-column field= "ShipCity" headerText="Ship City" width="150" foreignKeyField="ShipCity" foreignKeyValue="OrderID" [dataSource]='colData'></e-column> 
  </e-columns> 
</ejs-grid> 


export class AsyncPipeComponent { 
    . . . . .  
    public dataStateChange(state: DataStateChangeEventArgs): void { 
        this.service.execute(state); 
    } 
    public colData: any; 
    public ngOnInit(): void { 
        . . . . .  
        this.service.subscribe((args)=>{ 
        // you can directly assign json result to colData or assign to data manager 
        this.colData = new DataManager({json: (args as any).result}); 
      }); 
    } 



Regards, 
Thavasianand S. 



PV Prahal Venkatesan April 9, 2020 09:06 AM UTC

Hi Thavasi,

Can you please send me a sample where GraphQL adaptor is used to set the data for Schedule component. What I am trying to do now is I am fetching all data from the GraphQL/Nodejs server and storing it in a state variable within the parent component of Schedule component, but there are issues when I am adding/updating/deleting events in the Schedule component. Everything looks ok but there is flickering after data is fetched from backend. How to set the datasource of schedule to the graphql query? 

Thanks,
Prahal 


BS Balaji Sekar Syncfusion Team April 10, 2020 11:49 AM UTC

Hi Prahal,  

Thanks for the update.  

We have validated your reported query at our end and for that we have prepared a CRUD sample using custom CustomGraphQLAdaptor by extending it using UrlAdaptor and it can be downloaded from the following link.  

Code snippet:  
class CustomGraphQLAdaptor extends UrlAdaptor  
  processResponse(): Object {  
    let original: Object[] = super.processResponse.apply(this, arguments);  
    return original;  
  }  
}  
export class AppComponent {  
  public eventSettings: EventSettingsModel = {  
    dataSource: new DataManager({  
      url: 'http://localhost:54738/Home/LoadData', // Here need to mention the web api sample running path  
      crudUrl: 'http://localhost:54738/Home/UpdateData',  
      crossDomain: true,  
      adaptor: new CustomGraphQLAdaptor  
    }),  
  };  
}  
  
 

And for further reference kindly refer the below UG link,  
 

Kindly try the above CRUD sample and if you have any other concerns please revert for further assistance.  

Regards,    
Balaji Sekar. 


Loader.
Live Chat Icon For mobile
Up arrow icon