flat-fuchsia•17mo ago
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
flat-fuchsiaOP•17mo 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:
flat-fuchsiaOP•17mo 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
flat-fuchsiaOP•17mo 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
flat-fuchsiaOP•17mo 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
flat-fuchsiaOP•17mo 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
flat-fuchsiaOP•17mo 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
flat-fuchsiaOP•17mo 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