How to use RTK-Query with Supabase - reactjs

I have a project already configured with Supabase and using Redux-Toolkit. I have never used RTK-Query and I am just learning but after reading in the docs and looking for similar questions I have created a supabaseApi.js file which looks like:
import { createApi, fakeBaseQuery } from '#reduxjs/toolkit/query';
export const supabaseApi = createApi({ baseQuery: fakeBaseQuery(),
endpoints: (builder) =({
getStudents: builder.query({
queryFn: async () ={
const students = await supabase
.from('students')
.select()
return {students, error}
}
})
}) })
export const { useGetStudentsQuery } = supabaseApi;
However, when I call the useGetStudentsQuery() to get the students table I receive an error in the console telling me that "useGetStudentsQuery is not a function". I also noticed that when I begin to write the useGet function, it seems it hasn't been automatically created as I don't get the Visual Studio hints.
What is it that I am doing wrong? Thanks.

A few things:
to have the hooks, you have to import from '#reduxjs/toolkit/query/react';
the queryFn has to return either { data } or { error }, not { student }
your code does not seem to have a error variable, but tries to return it.
so:
import { createApi, fakeBaseQuery } from '#reduxjs/toolkit/query/react';
export const supabaseApi = createApi({ baseQuery: fakeBaseQuery(),
endpoints: (builder) =({
getStudents: builder.query({
queryFn: async () ={
const students = await supabase
.from('students')
.select()
return { data: students }
}
})
}) })
export const { useGetStudentsQuery } = supabaseApi;

Related

getState of undefined while using customFetchBase to refresh token with rtk query and nestJs

I receive this error
I tried to follow the official guide
officialGuyde
and this unofficial guide to understanding what to do. I also tried to see several repos, but i wasn't able to find a solution to this.
unofficialGuide
now this is how I set my apiSlice
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
import customFetchBase from "./customFetchBase";
export const apiSlice = createApi({
reducerPath: "api",
baseQuery: customFetchBase,
tagTypes: ["User", "Interests"],
endpoints: () => ({})
});
and this is the relative customFetchBase
import {
BaseQueryFn,
FetchArgs,
fetchBaseQuery,
FetchBaseQueryError
} from "#reduxjs/toolkit/query";
import { Mutex } from "async-mutex";
const baseUrl = `${process.env.BASE_URL}`;
// Create a new mutex
const mutex = new Mutex();
const baseQuery = fetchBaseQuery({
baseUrl
});
const customFetchBase: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
// wait until the mutex is available without locking it
await mutex.waitForUnlock();
let result = await baseQuery(args, api, extraOptions);
console.log("-> result", result);
if ((result.error?.data as any)?.message === "You are not logged in") {
if (!mutex.isLocked()) {
const release = await mutex.acquire();
console.log("-> release", release);
try {
const refreshResult = await baseQuery(
{ credentials: "include", url: "oauth/token" },
api,
extraOptions
);
console.log("-> refreshResult", refreshResult);
if (refreshResult.data) {
// Retry the initial query
result = await baseQuery(args, api, extraOptions);
}
/* else {
api.dispatch(logout());
window.location.href = "/login";
} */
} finally {
// release must be called once the mutex should be released again.
release();
}
} else {
// wait until the mutex is available without locking it
await mutex.waitForUnlock();
result = await baseQuery(args, api, extraOptions);
}
}
return result;
};
export default customFetchBase;
if i try to change
export const apiSlice = createApi({
reducerPath: "api",
baseQuery: fetchBaseQuery({ baseUrl: process.env.BASE_URL }) /// ----> different line from the previous code snippet
tagTypes: ["User", "Interests"],
endpoints: () => ({})
});
everything works fine. I tried to see several repos, but i didn't find anything that could help to understand what's going on, or what to do to debug. Can someone help me ?

Can't assign to object array when fetching data with RTK Query

I have come across a problem that I do not understand while trying to integrate redux toolkit and more specifically RTK Query into my project. All I want to do is fetch an object array from my backend using a query hook, pass this data into my component and alter some of the elements inside the data based on user actions.
I am copying the incoming array so as not to mutate the original.
I can replace entire objects in the array with 'blah' but if I try to alter a single value within one of the objects I get:
TypeError: Cannot assign to read only property 'title' of object '#<Object>'
This problem didn't arise when I was using fetch().
I have been stuck on this for days!!!
apiSlice
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react';
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: process.env.devUrl }),
tagTypes: ['categories'],
endpoints: (builder) => ({
getCategories: builder.query({
query: () => 'categories/includingJobs',
transformResponse: (response) => response.data.data,
providesTags: ['categories'],
}),
}),
});
export const { useGetCategoriesQuery} = apiSlice;
Component
import {
useGetCategoriesQuery,
} from '../features/api/apiSlice';
const Test = () => {
const {
data: categories,
isLoading,
isSuccess,
isError,
error,
} = useGetCategoriesQuery();
if (isSuccess) {
let categoriesCopy = JSON.parse(JSON.stringify(categories));
//This is the line that breaks everything. Why?
categoriesCopy[0].title = 'new title';
}
return <h1>Something rendered</h1>;
};
export default Test;

RTK Query with AppSync returns status "rejected"

I'm developing a react app using RTK Query & AppSync (graphQL).
I tried a query request as follows, but always the redux status is "rejected" saying "Cannot read properties of undefined (reading 'filter')" (Please check a pic below).
It seems the request itself is successfully done (200), so I guess it is due to the geaphQL client.
Redux Toolkit without RTK Query works as expected.🧐
Please help😭
RTK Query (rejected)
import { createApi } from '#reduxjs/toolkit/query/react';
import { graphqlRequestBaseQuery } from '#rtk-query/graphql-request-base-query';
import { API } from 'aws-amplify';
import { GRAPHQL_AUTH_MODE } from '#aws-amplify/api-graphql/lib/types';
import { listSurveyTitles } from 'src/graphql/queries';
import aws_exports from 'src/aws-exports';
API.configure(aws_exports);
export const surveyTitlesApi = createApi({
reducerPath: 'surveyTitles',
baseQuery: graphqlRequestBaseQuery({
url: '/graphql',
}),
endpoints: (builder) => ({
fetchSurveyTitles: builder.query({
query: ({ limit = 2147483647, params }) => ({
document: API.graphql({
query: listSurveyTitles,
variables: { limit, ...params },
authMode: GRAPHQL_AUTH_MODE.API_KEY,
}),
}),
}),
}),
});
export const { useFetchSurveyTitlesQuery } = surveyTitlesApi;
Slice with Redux Toolkit not RTK (fulfilled)
export const fetchSurveyTitles = createAsyncThunk(
'planner/fetchSurveyTitles',
async ({ limit = 2147483647, ...params }, thunkAPI) => {
try {
return await API.graphql({
query: listSurveyTitles,
variables: { limit, ...params },
authMode: GRAPHQL_AUTH_MODE.API_KEY,
});
} catch (e: any) {
return thunkAPI.rejectWithValue(e);
}
}
);
Showing same request payloads for the both approaches (200)
The way you have written that there, the return value of your query function would be fed into graphqlRequestBaseQuery, which in turn calls graphql-request - but you already have made your request and everything by using the amplify client.
If you want to use the amplify client, you don't need the graphqlRequestBaseQuery.
In that case, just use queryFn instead of query:
endpoints: (builder) => ({
fetchSurveyTitles: builder.query({
async queryFn ({ limit = 2147483647, ...params }) {
try {
const data = await API.graphql({
query: listSurveyTitles,
variables: { limit, ...params },
authMode: GRAPHQL_AUTH_MODE.API_KEY,
});
// it is important that the object you return either has the form `{data}` or `{error}`
return { data }
} catch (error: any) {
return { error }
}

Unable to delete or add data in firestore using RTK-Query in react

I am trying to achieve delete and add functionality in react using RTK-Query with firestore. It sound might be weird that I am using RTK Query to perform firestore operation in React. So, I have written service API file to delete and add operation with firestore. So, whenever I try to delete or add data in firestore with RTK Query, so I am getting some weird error in my console. However, when I refresh the application then I am seeing the updated data on my app after performing the add/delete operation. For some reason, initially it's not providing me correct result due to below error but after page refresh I am getting the updated value from firestore in my react app.
Here is code for service API
import { createApi, fakeBaseQuery } from "#reduxjs/toolkit/query/react";
import {
addDoc,
collection,
deleteDoc,
doc,
getDocs,
onSnapshot,
serverTimestamp,
} from "firebase/firestore";
import { db } from "../firebase";
export const contactsApi = createApi({
reducerPath: "api",
baseQuery: fakeBaseQuery(),
tagTypes: ["Contact"],
endpoints: (builder) => ({
contacts: builder.query({
async queryFn() {
try {
const userRef = collection(db, "users");
const querySnapshot = await getDocs(userRef);
let usersData = [];
querySnapshot?.forEach((doc) => {
usersData.push({
id: doc.id,
...doc.data(),
});
});
return { data: usersData };
} catch (err) {
console.log("err", err);
return { error: err };
}
},
providesTags: ["Contact"],
}),
addContact: builder.mutation({
async queryFn(contact) {
try {
await addDoc(collection(db, "users"), {
...contact,
timestamp: serverTimestamp(),
});
} catch (err) {
return { error: err ? err : null };
}
},
invalidatesTags: ["Contact"],
}),
deleteContact: builder.mutation({
async queryFn(id) {
try {
await deleteDoc(doc(db, "users", id));
} catch (err) {
if (err) {
return { error: err };
}
}
},
invalidatesTags: ["Contact"],
}),
}),
});
export const {
useContactsQuery,
useAddContactMutation,
useDeleteContactMutation,
} = contactsApi;
store.js file
import { configureStore } from "#reduxjs/toolkit";
import { contactsApi } from "./services/contactsApi";
import { setupListeners } from "#reduxjs/toolkit/query";
export const store = configureStore({
reducer: {
[contactsApi.reducerPath]: contactsApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
}).concat(contactsApi.middleware),
});
setupListeners(store.dispatch);
A queryFn has to always return an object with either a data property or an error property - in your case you only do that in the error case.
Try adding a return { data: 'ok' } if you don't have any better idea.

I have a problem with firebase after post a data

I'm working with RTK query in my react project as a fetching/caching module which is great but after POST a data to my firebase database something like a random id which made up by firebase subcategorizes all my data and disrupts the structure of my data
I put a picture which shows how data getting store on the firebase :
and below code is the RTK query handler
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
import {
AllBurgerType,
BurgerType,
} from "../*********************";
export const burgerApi = createApi({
reducerPath: "burgerApi",
tagTypes: ["Ingredients"],
baseQuery: fetchBaseQuery({
baseUrl:
"https://************************.firebasedatabase.app",
}),
endpoints: (builder) => ({
// I've rid other methods
addIngredients: builder.mutation({
query: (initialIngredients) => ({
url: "/.json",
method: "POST",
body: initialIngredients,
}),
invalidatesTags: ["Ingredients"],
}),
}),
});
export const {
useGetIngredientsQuery,
useAddIngredientsMutation,
useEditIngredientsMutation,
} = burgerApi;
and add new data like on the other file like this :
import { useAddIngredientsMutation } from "../../../../Api/apiSlice";
const [addNewIng, { isLoading, isSuccess }] =
useAddIngredientsMutation();
await addNewIng(store.getState().burger).unwrap();
how should I prevent this

Resources