Home > Software design >  rtk query ts error jwt does not exists on type
rtk query ts error jwt does not exists on type

Time:04-04

Why I get this error ?

Property 'jwt' does not exist on type '{ data: IAuthResponse; } | { error: FetchBaseQueryError | SerializedError; }'.
  Property 'jwt' does not exist on type '{ data: IAuthResponse; }'.ts(2339)

I use RTK Query and want to handle my response:

Query.tsx

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { IAuthLoginForm } from '../../../components/Login/Model';
import { IAuthResponse } from './Model';

export interface IAuthResponse {
  jwt: string;
  name: string;
  username: string;
  profile_name: string;
}

export const AuthFlow = createApi({
  reducerPath: 'AuthFlow',
  baseQuery: fetchBaseQuery({ baseUrl: 'http://192.168.0.249:4000/' }),
  endpoints: (builder) => ({
    login: builder.mutation<IAuthResponse, IAuthLoginForm>({
      query: (form) => ({
        url: '/login',
        method: 'POST',
        body: form
      })
    })
  })
});

export const { useLoginMutation } = AuthFlow;

Home.tsx

...
const [register, { data, error, isLoading }] = useLoginMutation();

const Submit = () => {
 const response = await register('test');
 
 if(response.jwt) {
   // ERROR above jwt not exists on property
 }
};

Why I get this error if I want to access .jwt ? I use it in my Model.. can anyone help me to solve this issue ?

CodePudding user response:

From the RTK Query docs:

The "mutation trigger" is a function that when called, will fire off the mutation request for that endpoint. Calling the "mutation trigger" returns a promise with an unwrap property, which can be called to unwrap the mutation call and provide the raw response/error. This can be useful if you wish to determine whether the mutation succeeds/fails inline at the call-site.

Your mutation trigger here is the register, so to access the data from your response with rtk query you should use one of this approaches:

const Submit = async (data: IAuthLoginForm) => {
 // note the unwrap here, you always use it to get the data
 await register(data).unwrap().then((response) => {
   // Handle the response here
   console.log(response)
 });
};

Or use the useEffect hook to get the response data

const Submit = (data: IAuthLoginForm) => {
 register(data)
};

useEffect(() => {
   // use the const data to get the response
   console.log(data)
}, [data])

to handle errors you can call .catch nested to .then like this:

const Submit = async (data: IAuthLoginForm) => {
 await register(data).unwrap().then((response) => {
   // Handle the response here
   console.log(response)
 }).catch((error) => {
   // Handle the error here
   console.log(error)})
};

Or you can use the const error from your useLoginMutation inside an useEffect just like i did with the const data:

useEffect(() => {
   // use the const error to get the error
   console.log(error)
}, [error])

One last thing, to send the data properly to the server, the data that comes from the submit should be the same type of the data that you defined in your builder.mutation<IAuthResponse, IAuthLoginForm>

So you have also two approaches here:

const Submit = async (data: IAuthLoginForm) => {
 // send the same data type from submit and just pass to register
 await register(data).unwrap().then((response) => {
   // Handle the response here
   console.log(response)
 });
};

Or pass each data individually to register like so:

const Submit = async (data: IAuthLoginForm) => {
 // note that i used an example here because i don't know how your interface IAuthLoginForm looks like
 await register({data1: data.data1, data2: data.data2 }).unwrap().then((response) => {
   // Handle the response here
   console.log(response)
 });
};

Some reference about the unwrap and mutations for you: Frequently Used Mutation Hook Return Values

  • Related