Search code examples
websocketsocket.iortk-query

RTK query receiving websocket updates but not refreshing page


In my CRUD app I'm using socket.io and RTK query for data fetching. The problem is I have to reload the page to see updates - my sockets are working (I can see requests going one after another, and after making some changes in 1st client those changes are present in 2nd client network request tab), but I cannot achieve refreshing the page after the updated data is received. I was trying to achieve this via "updateCachedData" because I suspect it should resolve my problem by I cannot get it to work. My data that is fetched is in format of array of objects and I'm fetching whole array every time to and want to replace it in "updateCachedData" probably. What is the problem here and how can I have access to reponse with this data received through socket? Here is my RTK api slice

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { io } from "socket.io-client";

const API_URL = process.env.REACT_APP_SERVER_ENDPOINT;

export const recordsApi = createApi({
  reducerPath: "recordsApi",
  baseQuery: fetchBaseQuery({
    baseUrl: `${API_URL}/api/users`,
    credentials: "include",
  }),
  tagTypes: ["Records"],
  endpoints: (builder) => ({
    getRecords: builder.query({
      query: () => ({
        url: "/",
      }),
      async onCacheEntryAdded(
        arg,
        { updateCachedData, cacheDataLoaded, cacheEntryRemoved }
      ) {
        try {
          await cacheDataLoaded;
          const socket = io(API_URL, {
            path: "/api/users",
            withCredentials: true,
          });
          
          socket.on("connect", () => {
    
            updateCachedData('getRecords', response, (draft) => {
              return [...draft, response];
            });
          });
          console.log(`Socket: ${socket.connected}`);
          await cacheEntryRemoved;
        } catch {
          console.log("error");
        }
      },
      
      providesTags: ["Records"],
    }),
    addRecord: builder.mutation({
      query: (record) => ({
        url: "/",
        method: "POST",
        body: record,
      }),
      invalidatesTags: ["Records"],
    }),
    updateRecord: builder.mutation({
      query: (editedRecord) => ({
        url: `/${editedRecord.recordToChangeId}`,
        method: "PUT",
        body: editedRecord.userValues,
      }),
      invalidatesTags: ["Records"],
    }),
    removeRecord: builder.mutation({
      query: (id) => ({
        url: `/${id}`,
        method: "DELETE",
        body: id,
      }),
      invalidatesTags: ["Records"],
    }),
  }),
});
export const {
  useGetRecordsQuery,
  useAddRecordMutation,
  useUpdateRecordMutation,
  useRemoveRecordMutation,
} = recordsApi;
export default recordsApi.reducer;

What am I doing wrong?


Solution

  • You are calling updateCachedData wrong. It is always set up to update the current cache entry, so you don't have to pass in an endpoint name or an argument for a cache key.

    updateCachedData((draft) => {
                  return [...draft, response];
                });