Hi there,
I am attempting to use the Syncfusion data grid to display paged (only pulling each page as needed, not all at once) data retrieved from an AWS Amplify GraphQL provider. Amplify generates Javascript helpers for accessing the data so a direct interface from the grid to GraphQL isn't necessary, just the ability to manually call promise based Javascript methods. I'm having trouble finding any way to do this. Nearly everything I've found online points to one of two methods: Create a custom adaptor and use it with DataManager or handle the DataStateChange event manually. I've tried both methods and run into issues with them.
Custom Adaptor
Here's the code for my grid component:
<template>
<div>
<ejs-grid :dataSource="data">
<e-columns>
<e-column field="Name" headerText="Name"></e-column>
<e-column field="Description" headerText="Description"></e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import { DataManager } from '@syncfusion/ej2-data';
import CustomAdaptor from '@/utils/customAdaptor';
export default {
name: 'MyList',
provide: {
grid: [CommandColumn]
},
data() {
return {
data: new DataManager({
adaptor: new CustomAdaptor()
})
}
}
}
</script>
And the custom adaptor (latest a:
import { Adaptor } from "@syncfusion/ej2-data";
import { API, graphqlOperation } from 'aws-amplify';
import * as queries from '@/graphql/queries';
export default class CustomAdaptor extends Adaptor {
async processQuery() {
return API.graphql(graphqlOperation(queries.listMyData));
}
processResponse() {
//calling base class processResponse function
let original = super.processResponse.apply(this, arguments);
console.log(original);
return { result: original.result, count: original.count };
}
}
The problem here is that processResponse seems to get called immediately and the promise returned by API.graphql doesn't get resolved. I also tried awaiting the call in processQuery with no luck. From reading everything online (docs, and forum responses) it appears there is no way to inject custom code to actually get the data, just to adjust the query and adjust the final data.
DataStateChange
I tried a couple of different methods for this (found in different places online)
Try 1
<template>
<div>
<h1>Sound Fonts</h1>
<ejs-grid :dataSource="data" @dataStateChange="dataStateChange" @load="initialLoad" :allowPaging="true" :pageSettings="pageSettings">
<e-columns>
<e-column field="name" headerText="Name"></e-column>
<e-column field="description" headerText="Description"></e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import { Page } from '@syncfusion/ej2-vue-grids';
import { API, graphqlOperation } from 'aws-amplify';
import * as queries from '@/graphql/queries';
export default {
name: 'SoundFontsList',
provide: {
grid: [Page]
},
data() {
return {
data: [],
pageSettings: { pageSize: 5 }
}
},
methods: {
dataStateChange: async function(args) {
const result = await API.graphql(graphqlOperation(queries.listSoundFonts));
this.data = result.data.listSoundFonts.items;
},
initialLoad: async function() {
const result = await API.graphql(graphqlOperation(queries.listSoundFonts));
this.data = result.data.listSoundFonts.items;
}
}
}
</script>
The problem here is that the data from the initialLoad method appears but I can't figure out how to tell the pager what the total number of entries is (without pulling all the data which is what this code is doing) so that it can properly show the page count, etc.
Try 2
<template>
<div>
<h1>Sound Fonts</h1>
<ejs-grid :dataSource="data" @dataStateChange="dataStateChange" @load="initialLoad" :allowPaging="true" :pageSettings="pageSettings">
<e-columns>
<e-column field="name" headerText="Name"></e-column>
<e-column field="description" headerText="Description"></e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import { Page } from '@syncfusion/ej2-vue-grids';
import { API, graphqlOperation } from 'aws-amplify';
import * as queries from '@/graphql/queries';
export default {
name: 'SoundFontsList',
provide: {
grid: [Page]
},
data() {
return {
data: { results: [], count: 0 },
pageSettings: { pageSize: 5 }
}
},
methods: {
dataStateChange: async function(args) {
const result = await API.graphql(graphqlOperation(queries.listSoundFonts));
this.data.results = result.data.listSoundFonts.items;
this.data.count = result.data.listSoundFonts.items.length;
},
initialLoad: async function() {
const result = await API.graphql(graphqlOperation(queries.listSoundFonts));
this.data.results = result.data.listSoundFonts.items;
this.data.count = result.data.listSoundFonts.items.length;
}
}
}
</script>
In this situation, the grid never shows any data.
Any help in finding the correct path would be greatly appreciated as I've spent way too much time on this already.
Thanks,
Jason