orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
2.8k stars 311 forks source link

React Query: Support passing `query.meta` / `mutation.meta` options to axios instance #1317

Open kennyhei opened 4 months ago

kennyhei commented 4 months ago

In react-query, you can pass additional options to queryFn by setting meta options. In functions generated by orval, it would look like this:


// query function
const { data } = useGetData(id, { query: { meta: { extraData: 1 } });

// mutation function
const { mutate } = usePostData({ mutation: { meta: { extraData: 1 } });

What were you expecting to happen?

I'd like to pass extra/meta options to axios instance itself and I expected that functions generated by orval will automatically pass any extra options (or options.meta) to queryFn and therefore to (custom) axios instance like this:

const useGetDataQueryOptions(options) {
    ...
    const useGetDataFn = useGetDataHook();
    const queryFn = ({ signal }) => useGetDataFn(id, signal, options);
    ...
}

const useGetDataHook = () => {
    const getData = customAxiosInstance();
    return (id, signal, options) => {
        return getData({ url: ..., method: 'GET', signal, options });
    }
}

But instead, the options are not passed to axios instance, only url, method and signal (+ and possibly params + request data if it's POST/PATCH/PUT request).

Am I missing something because in the docs about "Custom Axios Instance" in the code example the custom instance has parameters "config" and "options": https://orval.dev/guides/custom-axios

It doesn't have to be necessarily react-query's meta options that we pass to custom axios instance. Any way to pass extra data to axios instance (out-of-the-box) would be really nice.

What versions are you using?

Operating System: OSX, macOS Sonoma 14.4.1 Package Version: 6.25.0 Browser Version: Chrome Version 123.0.6312.87

kennyhei commented 4 months ago

Use case would be to determine whether to show automatic success notification. For like 99% of my endpoints I want to automatically show message when request is successful but there are a few exceptions where I would like to disable the feature. Here's my custom axios instance:

export const useAxios = <T>(): ((config: AxiosRequestConfig) => Promise<T>) => {
    const { access_token, language } = useSelector((state: RootStateType) => state.user);
    const { showSuccess } = useSnackbars();

    return (config: AxiosRequestConfig) => {
        const method = config.method || '';
        const controller = new AbortController();
        const promise = AXIOS_INSTANCE({
            ...config,
            headers: {
                Authorization: `Bearer ${access_token || ''}`,
                'Accept-Language': language,
            },
            signal: controller.signal,
            paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'repeat' }),
        })
        .then(({ data }) => {
            // TODO: How to disable this if notification is unwanted?
            const action = {
                POST: 'create',
                PUT: 'update',
                PATCH: 'update',
                DELETE: 'delete',
            }[method];
            action && showSuccess(action as Action);
            return data;
        })

        // @ts-ignore
        promise.cancel = (): void => {
            controller.abort('Query was cancelled by React Query');
        };

        return promise;
    };
};

export type ErrorType<Error> = AxiosError<Error>;

If the options would be passed to axios instance, I could then disable calling showSuccess:

return (config: AxiosRequestConfig, options: any) => {
    ...
    if (action && !options.meta.disableNotifications) {
        showSuccess(action);
    }
Michal905 commented 3 months ago

It would be great to have this feature implemented. I have the same problem; I don't have a way to pass custom data to the global handler to disable notifications.

melloware commented 3 months ago

PR is always welcome.