refinedev / refine

A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.
https://refine.dev
MIT License
27.73k stars 2.15k forks source link

[BUG] getOne method doesn't use `meta.gqlVariables` in `@refinedev/hasura` #6374

Open vrrashkov opened 4 days ago

vrrashkov commented 4 days ago

Describe the bug

Trying to pass custom variables other than ID to a query is not working. Here is the code that I have. I am using useForm and what in my getOne query to have extra variable not only the ID.

  const { formProps: editFormProps, saveButtonProps: editSaveButtonProps } =
    useForm<
      GetFields<UpdateSettingValueMutation>,
      HttpError,
      GetVariables<UpdateSettingValueMutationVariables>
    >({
      action: "edit",
      resource: "settings",
      id: editingId?.toString(),
      meta: {
        gqlQuery: SETTINGS_WITH_VALUES_DATA_QUERY,
        gqlMutation: UPDATE_SETTING_VALUES_MUTATION,
        gqlVariables: {
          extraValue: 1,
        },
      },
      queryMeta: {
        meta: {
          extraValue: 1,
        },
        gqlVariables: {
          extraValue: 1,
        },
      },
      queryOptions: {
        meta: {
          extraValue: 1,
        },
      },
      mutationMode: "pessimistic",
      onMutationSuccess: () => {
        setEditingId(null);
      },
    });

My graphql is this:

export const SETTINGS_WITH_VALUES_DATA_QUERY = gql`
  query SettingsWithValuesDataOne($id: ID!, $extraValue: Int!) {
    setting(id: $id, extraValue: $extraValue) {
        ...SettingsWithValuesDataFields
    }
  }
  ${SETTINGS_WITH_VALUES_DATA_FIELDS},
`;

I am not sure if I am missing something from the documentation but i have tried multiple ways as you can see in the above code and nothing seems to be helping it always sends onlyvariables : {id: "1"} , the extraValue i am trying to pass its not there.

Steps To Reproduce

Test with the code provided

Expected behavior

Custom variables should be included

Packages

Additional Context

No response

vrrashkov commented 3 days ago

I am trying to do something more simple like this and it still doesnt work it only passes the ID, nothing changes there is no extraValue.

const { data, isLoading, isError } = useOne({
    resource: "settings",
    id: 1,
    meta: {
      gqlQuery: SETTINGS_WITH_VALUES_DATA_QUERY,
      variables: {
        extraValue: 2,
      },
      gqlVariables: {
        extraValue: 2,
      },
    },
    queryOptions: {
      enabled: true,
    },
  });

Inside my DataProvider i have this:

   getOne: async (...args) => {
      try {
        return await dataProvider.getOne(...args);
      } catch (error) {
        throw error;
      }
    },

I managed to pass variables by changing it to this:

    getOne: async ({ resource, id, meta }) => {
      try {
        // Extract custom variables from meta
        const customVariables = meta?.variables || {};

        const variables = {
          id,
          ...customVariables,
        };

        const query = meta?.gqlQuery!;

        const response = await client.request<BaseRecord>(query, variables);

        return {
          data: response[meta?.operation!],
        };
      } catch (error) {
        throw error;
      }
    },

But is this correct? I dont want to write custom logic for something that already exists like passing a custom varaible?

aliemir commented 2 days ago

Hey @vrrashkov sorry for the issue! Looks like the PR https://github.com/refinedev/refine/pull/6222 missed updating the getOne method for meta.gqlVariables. You can see that getMany, getList and mutation methods have the necessary implementation but getOne misses it. This is an issue with @refinedev/hasura rather than @refinedev/antd.

We'll be happy to see your contribution, if you can prepare a PR with the fix. Until this is fixed and released, you can stick with your workaround for the getOne.

I'll update the issue title since this is not related with @refinedev/antd 🙏