Not getting useList with Hasura as GraphQL provider to work
This is my dataProvider:
This is my query:
24 Replies
Hi @Henrik. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
It looks like you're encountering issues with the
useList
hook when using Hasura as your GraphQL provider with the graphql-default
naming convention. This is a known issue and has been discussed in the community.
Issue Description
When using the graphql-default
naming convention, the useList
hook may fail due to the way the aggregate operation is handled. Specifically, the getList
function in the Hasura provider expects a certain structure that may not align with the graphql-default
naming convention.
Solution
To resolve this issue, you can modify the Hasura provider to correctly handle the graphql-default
naming convention. This involves ensuring that the aggregate operation is correctly camelized.
Steps to Fix
1. Modify the Hasura Provider: You need to adjust the Hasura provider to handle the graphql-default
naming convention correctly. This can be done by swizzling the provider to use a camelized aggregate operation.
2. Example Configuration:
Here is an example of how you can configure your project to use the graphql-default
naming convention:
3. Set Naming Convention:
Add the namingConvention
settings to the Hasura provider in your src/App.tsx
:
Additional Resources
- Hasura Provider Example (https://refine.dev/docs/data/packages/hasura/#example)
- DataProvider Tutorial (https://refine.dev/docs/tutorial/understanding-dataprovider/index/)
Relevant Issues and Discussions
- Github Issue #4574 (https://github.com/refinedev/refine/issues/4574): Discusses the problem with list retrieval when using the graphql-default
naming convention.
- Github Issue #3828 (https://github.com/refinedev/refine/issues/3828): Discusses issues related to the DataProvider configuration.
By following these steps, you should be able to resolve the issues with the useList
hook when using Hasura as your GraphQL provider with the graphql-default
naming convention. If you continue to experience issues, consider reviewing the linked issues and discussions for more context and potential solutions.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai
This is the implementation with useList
I get error:
tasks-chart.tsx:45 Error fetching task chart data TypeError: Cannot read properties of undefined (reading 'aggregate')
Let me check the knowledge base for you. One moment! :books:
rival-blackOP•8mo ago
@kapa.ai
This is the response in network console (as expected):
Let me check the knowledge base for you. One moment! :books:
----------------------
It looks like the error you're encountering is due to the
aggregate
property being undefined
in the response. This is a known issue when using the graphql-default
naming convention with Hasura, as discussed in Github Issue #4574 (https://github.com/refinedev/refine/issues/4574).
Solution
To resolve this issue, you need to ensure that the aggregate operation is correctly camelized in the Hasura provider. Here’s how you can adjust your implementation:
1. Modify the Hasura Provider:
Ensure that the dataProvider
is correctly configured to use the graphql-default
naming convention:
2. Adjust the Query and Data Handling:
Ensure that your query and data handling logic correctly account for the graphql-default
naming convention. Here’s your updated component:
``typescript
import React, { useMemo } from "react";
import { useList } from "@refinedev/core";
import { gql } from "graphql-tag";
import { DashboardTasksChartQuery } from "interfaces"; // Adjust the import as necessary
export const DASHBOARD_TASKS_CHART_QUERY = gql
query DashboardTasksChart(
$where: TaskStagesBoolExp!
$orderBy: [TaskStagesOrderBy!]
$limit: Int!
$offset: Int!
) {
taskStages(where: $where, orderBy: $orderBy, limit: $limit, offset: $offset) {
title
tasksAggregate {
aggregate {
count(columns: id)
}
}
}
}
`;
export const DashboardTasksChart: React.FC = () => {
const { data, isError, error } = useList<DashboardTasksChartQuery>({
resource: "taskStages",
pagination: {
pageSize: 4,
},
filters: [
{
field: "title",
operator: "contains",
value: "",
},
],
sorters: [
{
field: "title",
order: "asc",
},
],
meta: {
gqlQuery: DASHBOARD_TASKS_CHART_QUERY
},
});
if (isError) {
console.error("Error fetching task chart data", error);
return null;
}
const tasksData = useMemo(() => {
if (!data?.data?.length) {
return [];
}
return data.data
.map((stage) => ({
title: stage.title,
value: stage.tasksAggregate?.aggregate?.count ?? 0,
}))
.filter(
(stage) =>
stage.value !== null && stage.value !== undefined && stage.value > 0,
)
.sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
},
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
----------------------
Based on the response you provided from the network console, it looks like the GraphQL query is returning the expected data structure. However, the issue might be related to how the
useList
hook is interpreting this response.
Steps to Ensure Compatibility
1. Check Data Provider Configuration:
Ensure that your data provider is correctly configured to handle the graphql-default
naming convention. This involves making sure that the aggregate operations are correctly camelized.
2. Ensure Correct Query Structure:
Make sure your query is structured correctly to match the expected response format.
3. Handling the Response in useList
:
Ensure that the useList
hook is correctly interpreting the response. You might need to map the response to the expected format if there are discrepancies.
Example Usage of useList
:
Additional Resources
- Hasura Provider Example (https://refine.dev/docs/data/packages/hasura/#example)
- DataProvider Tutorial (https://refine.dev/docs/tutorial/understanding-dataprovider/index/)
By following these steps, you should be able to ensure that the useList
hook works correctly with your Hasura GraphQL provider. If you continue to experience issues, consider reviewing the linked resources for more context and potential solutions.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai This is the type:
export type DashboardTasksChartQuery = {
taskStages: Array<
Pick<Types.TaskStages, "title"> & {
tasksAggregate: {
aggregate?: Types.Maybe<Pick<Types.TasksAggregateFields, "count">>;
};
}
>;
};
Why is useList with GetFieldsFromList reading aggregate?
export const DashboardTasksChart: React.FC = () => {
const { list } = useNavigation();
const { data, isError, error } = useList<
GetFieldsFromList<DashboardTasksChartQuery>
>({
resource: "taskStages",
pagination: {
pageSize: 4,
},
filters: [
{
field: "title",
operator: "contains",
value: "",
},
],
sorters: [
{
field: "title",
order: "asc",
},
],
meta: {
gqlQuery: DASHBOARD_TASKS_CHART_QUERY
},
});
if (isError) { console.error("Error fetching task chart data", error); return null; }
// console.log("Fetched data:", data); const tasksData = useMemo(() => { if (!data?.data?.length) { return []; }
if (isError) { console.error("Error fetching task chart data", error); return null; }
// console.log("Fetched data:", data); const tasksData = useMemo(() => { if (!data?.data?.length) { return []; }
Let me check the knowledge base for you. One moment! :books:
----------------------
The issue you're encountering with
useList
and GetFieldsFromList
reading the aggregate
property might be due to the type mismatch or incorrect usage of GetFieldsFromList
.
Understanding GetFieldsFromList
The GetFieldsFromList
utility type is used to extract fields from a GraphQL query result type. However, it seems that in your case, the aggregate
field is being read incorrectly.
Correct Usage of useList
To ensure that useList
works correctly with your GraphQL query and types, you should directly use the type DashboardTasksChartQuery
instead of GetFieldsFromList
.
Example Implementation
Here’s how you can adjust your implementation:
1. Define the Query Type:
Ensure that your query type is correctly defined to match the GraphQL response.
2. Use useList
with the Correct Type:
Use the DashboardTasksChartQuery
type directly in the useList
hook.
``typescript
import React, { useMemo } from "react";
import { useList } from "@refinedev/core";
import { gql } from "@apollo/client";
import { DashboardTasksChartQuery } from "interfaces"; // Adjust the import as necessary
export const DASHBOARD_TASKS_CHART_QUERY = gql
query DashboardTasksChart(
$where: TaskStagesBoolExp!
$orderBy: [TaskStagesOrderBy!]
$limit: Int!
$offset: Int!
) {
taskStages(where: $where, orderBy: $orderBy, limit: $limit, offset: $offset) {
title
tasksAggregate {
aggregate {
count(columns: id)
}
}
}
}
`;
export const DashboardTasksChart: React.FC = () => {
const { data, isError, error } = useList<DashboardTasksChartQuery>({
resource: "taskStages",
pagination: {
pageSize: 4,
},
filters: [
{
field: "title",
operator: "contains",
value: "",
},
],
sorters: [
{
field: "title",
order: "asc",
},
],
meta: {
gqlQuery: DASHBOARD_TASKS_CHART_QUERY
},
});
if (isError) {
console.error("Error fetching task chart data", error);
return null;
}
const tasksData = useMemo(() => {
if (!data?.data?.taskStages?.length) {
return [];
}
return data.data.taskStages
.map((stage) => ({
title: stage.title,
value: stage.tasksAggregate?.aggregate?.count ?? 0,
}))
.filter(
(stage) =>
stage.value !== null && stage.value !== undefined && stage.value > 0,
)
.sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
}, [data?.data]);
return (
<div>
{tasksData.map((task) => (
<div key={task.title}>
<h3>{task.title}</h3>
<p>Count: {task.value}</p>
</div>
))}
</div>
);
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai What is the expected output, when using Hasura as data provider for useList<GetFieldsFromList<>> ?
Let me check the knowledge base for you. One moment! :books:
----------------------
When using Hasura as a data provider for
useList<GetFieldsFromList<>>
, the expected output should be a normalized list of items based on the fields specified in your GraphQL query. The GetFieldsFromList
utility type is used to extract the fields from your offset-paginated list queries.
Example Query and Type
Here’s an example of a GraphQL query and the corresponding TypeScript type:
Using useList
with GetFieldsFromList
When you use useList<GetFieldsFromList<DashboardTasksChartQuery>>
, the expected output should be a list of taskStages
with the fields title
and tasksAggregate.aggregate.count
.
Example Implementation
Here’s how you can implement useList
with GetFieldsFromList
:
``typescript
import React, { useMemo } from "react";
import { useList } from "@refinedev/core";
import { gql } from "@apollo/client";
import { DashboardTasksChartQuery } from "interfaces"; // Adjust the import as necessary
export const DASHBOARD_TASKS_CHART_QUERY = gql
query DashboardTasksChart(
$where: TaskStagesBoolExp!
$orderBy: [TaskStagesOrderBy!]
$limit: Int!
$offset: Int!
) {
taskStages(where: $where, orderBy: $orderBy, limit: $limit, offset: $offset) {
title
tasksAggregate {
aggregate {
count(columns: id)
}
}
}
}
`;
export const DashboardTasksChart: React.FC = () => {
const { data, isError, error } = useList<GetFieldsFromList<DashboardTasksChartQuery>>({
resource: "taskStages",
pagination: {
pageSize: 4,
},
filters: [
{
field: "title",
operator: "contains",
value: "",
},
],
sorters: [
{
field: "title",
order: "asc",
},
],
meta: {
gqlQuery: DASHBOARD_TASKS_CHART_QUERY
},
});
if (isError) {
console.error("Error fetching task chart data", error);
return null;
}
const tasksData = useMemo(() => {
if (!data?.data?.length) {
return [];
}
return data.data
.map((stage) => ({
title: stage.title,
value: stage.tasksAggregate?.aggregate?.count ?? 0,
}))
.filter(
(stage) =>
stage.value !== null && stage.value !== undefined && stage.value > 0,
)
.sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
}, [data?.data]);
return (
<div>
{tasks
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai With this data response:
{
"data": {
"taskStages": [
{
"title": "active",
"tasksAggregate": {
"aggregate": {
"count": 1
}
}
},
{
"title": "inactive",
"tasksAggregate": {
"aggregate": {
"count": 1
}
}
}
]
}
}
I get:
TypeError: Cannot read properties of undefined (reading 'aggregate')
at getList (@refinedev_hasura.js?v=0869cb55:12770:38)
What do I need to do? Do I need to customize the data provider to handle this, or is there any other solution?
Let me check the knowledge base for you. One moment! :books:
----------------------
The error you're encountering,
TypeError: Cannot read properties of undefined (reading 'aggregate')
, suggests that the getList
function in the Hasura data provider is not correctly handling the response structure when using the graphql-default
naming convention.
Solution
You need to customize the Hasura data provider to correctly handle the graphql-default
naming convention. This involves ensuring that the aggregate operation is correctly camelized.
Steps to Customize the Data Provider
1. Swizzle the Data Provider:
Use the swizzle
command to customize the Hasura data provider.
2. Select the Hasura Data Provider:
Choose @refinedev/hasura
from the list of available data providers.
3. Modify the Data Provider:
Edit the /hasura-data-provider/index.ts
file to customize the data provider. Specifically, you need to modify the getList
function to handle the graphql-default
naming convention.
4. Use the Customized Data Provider:
Pass the customized data provider to the Refine
component.
Additional Resources
- Hasura Provider Example (https://refine.dev/docs/data/packages/hasura/#example)
- DataProvider Tutorial (https://refine.dev/docs/tutorial/understanding-dataprovider/index/)
By following these steps, you should be able to resolve the issue with the getList
function and ensure that the useList
hook works correctly with your Hasura GraphQL provider using the graphql-default
naming convention. If you continue to experience issues, consider reviewing the linked resources for more context and potential solutions.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai I already have support for the graphql-default naming convention
Let me check the knowledge base for you. One moment! :books:
----------------------
Given that you already have support for the
graphql-default
naming convention, the issue might be related to how the useList
hook is interpreting the response structure. The error TypeError: Cannot read properties of undefined (reading 'aggregate')
suggests that the aggregate
property is not being accessed correctly.
Solution
To resolve this issue, you need to ensure that the useList
hook correctly interprets the response structure. Here’s how you can adjust your implementation:
1. Ensure Correct Query Structure:
Make sure your GraphQL query is structured correctly to match the expected response format.
2. Use useList
with Correct Type:
Use the DashboardTasksChartQuery
type directly in the useList
hook.
Additional Resources
- Hasura Provider Example (https://refine.dev/docs/data/packages/hasura/#example)
- DataProvider Tutorial (https://refine.dev/docs/tutorial/understanding-dataprovider/index/)
By following these steps, you should be able to resolve the issue with the getList
function and ensure that the useList
hook works correctly with your Hasura GraphQL provider using the graphql-default
naming
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-blackOP•8mo ago
@kapa.ai export type DashboardTasksChartQuery = {
taskStages: Array<
Pick<Types.TaskStages, "title"> & {
tasksAggregate: {
aggregate?: Types.Maybe<Pick<Types.TasksAggregateFields, "count">>;
};
}
>;
};
Property 'taskStages' does not exist on type 'DashboardTasksChartQuery[]'. for if (!data?.data?.taskStages?.length) {. Why?
Let me check the knowledge base for you. One moment! :books:
----------------------
The error
Property 'taskStages' does not exist on type 'DashboardTasksChartQuery[]'
suggests that the data
property returned by useList
is being interpreted as an array of DashboardTasksChartQuery
objects, rather than a single object containing the taskStages
array.
Solution
To resolve this issue, you need to ensure that the data
property is correctly typed and accessed. Here’s how you can adjust your implementation:
1. Correct the Type Definition:
Ensure that the DashboardTasksChartQuery
type is correctly defined to match the expected response structure.
2. Use useList
with Correct Type:
Use the DashboardTasksChartQuery
type directly in the useList
hook and ensure that the data
property is accessed correctly.
Additional Resources
- Hasura Provider Example (https://refine.dev/docs/data/packages/hasura/#example)
- [DataProvider Tutorial](https
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@135097094825443328> kapa.ai is still learning and improving, please let us know how it did by reacting below