redux-toolkitputrtk-querymutation

how to pass data to redux toolkit mutation


In component,

const [ updateproductapi ] = useUpdateProductMutation()
formdata.append("product_name", product.product_name);
formdata.append("product_price", product.product_price);
formdata.append("file", imagefile)

updateproductapi(product.product_id, formdata)

In ApiSlice,

updateProduct: builder.mutation({
            query: (product_id, formdata ) => ({
                url: `/product/${product_id}`,
                //url: '/product/24',
                method: 'PUT',
                body: formdata,
            }),
            invalidatesTags: ['Productmgmt']
        }),

When data send to backend program, my backend program will get undefined. I send raw data to backend, req.body will show data. How to solve my problem. Thank you very much.


Solution

  • Issue

    The query consumes only a single argument.

    query signature

    export type query = <QueryArg>(
      arg: QueryArg,
    ) => string | Record<string, unknown>
    
    // with `fetchBaseQuery`
    export type query = <QueryArg>(arg: QueryArg) => string | FetchArgs
    

    You are trying to pass two arguments though:

    query: (product_id, formdata ) => ({
      url: `/product/${product_id}`,
      method: 'PUT',
      body: formdata,
    }),
    
    const [updateProductApi] = useUpdateProductMutation();
    formdata.append("product_name", product.product_name);
    formdata.append("product_price", product.product_price);
    formdata.append("file", imagefile);
    
    updateProductApi(product.product_id, formdata);
    

    This causes formdata to be undefined in the mutation request.

    Solution Suggestion

    Update your endpoint logic to consume a single argument object with all the data properties you need.

    Example:

    query: ({ productId, formData }) => ({
      url: `/product/${productId}`,
      method: 'PUT',
      body: formData,
    }),
    
    const [updateProductApi] = useUpdateProductMutation();
    formData.append("product_name", product.product_name);
    formData.append("product_price", product.product_price);
    formData.append("file", imagefile);
    
    updateProductApi({
      productId: product.product_id,
      formData
    });
    

    You might even want to just pass the entire product object and compose the request and payload in the query function. This simplifies your API and reduces the workload on useUpdateProductMutation callers.

    Example:

    query: (product) => {
      const formData = new FormData();
    
      formData.append("product_name", product.product_name);
      formData.append("product_price", product.product_price);
      formData.append("file", imagefile);
    
      return {
        url: `/product/${product.product_id}`,
        method: 'PUT',
        body: formData,
      };
    },
    
    const [updateProductApi] = useUpdateProductMutation();
    
    updateProductApi(product);