0

I have an authentication system. calling Api's using tanstack query.

When logging in, signing up, and verifying email using the link, everything works fine. However, when I check the mutation's isSuccess state, it remains false even after I receive the success response.

I also have authTypes.ts, and all of them match the response.

Github Repo: https://github.com/0xHuzaifa/Video-Streaming-Site/tree/main/client

authQuery.ts

const loginMutationOptions = (
  navigate: ReturnType<typeof useNavigate>,
  options?: Partial<UseMutationOptions<AuthResponse, Error, LoginSchemaType>>
) => {
  const { setUser, setIsLogin } = useAppContext();
  return useMutation({
    mutationKey: ["login"], // Add a unique mutation key
    mutationFn: (data: LoginSchemaType) => login(data),
    onSuccess: (
      data: AuthResponse,
      variables: LoginSchemaType,
      context?: unknown
    ) => {
      // Handle unverified user
      if (isUnverifiedAuth(data)) {
        console.log("unverified user", data);
        toast.info(data.message || "Please verify your email first");
        navigate("/verify-email");
      }

      // Handle successful login for verified user
      if (isSuccessfulAuth(data)) {
        localStorage.setItem("user", JSON.stringify(data?.data?.loggedInUser));
        setUser(data?.data?.loggedInUser);
        localStorage.setItem("isLogin", "true");
        setIsLogin(true);
        toast.success(data.message || "Login successful");
        console.log("login successful", data);
      }

      options?.onSuccess?.(data, variables, context);
    },

    onError: (error: Error, variables: LoginSchemaType, context?: unknown) => {
      console.log("login failed", error);
      const message = getErrorMessage(error);
      console.log("error message", message);
      toast.error(message);
      options?.onError?.(error, variables, context);
    },
    ...options,
  });
};

const login = async (data: LoginSchemaType): Promise<AuthResponse> => {
  try {
    const response = await api.post("/auth/login", data);
    console.log("Login response:", {
      status: response.status,
      data: response.data,
      headers: response.headers,
    });
    return response.data;
  } catch (error: any) {
    console.error("Login request failed:", error.response?.data || error.message);
    throw new Error(error.response?.data?.message || "Login failed");
  }
};

loginForm.tsx

// Mutation for login
  // This uses React Query's useMutation hook to handle the login process
  const loginMutation = loginMutationOptions(navigate);

  const onSubmit: SubmitHandler<LoginSchemaType> = async (data) => {
    loginMutation.mutate(data);
  };

  // Add useEffect to log state changes
  useEffect(() => {
    console.log("Mutation state updated:", {
      isPending: loginMutation.isPending,
      isSuccess: loginMutation.isSuccess,
      isError: loginMutation.isError,
      status: loginMutation.status,
      data: loginMutation.data,
      error: loginMutation.error,
      variables: loginMutation.variables,
      submittedAt: loginMutation.submittedAt,
    });
  }, [
    loginMutation.isPending,
    loginMutation.isSuccess,
    loginMutation.isError,
    loginMutation.status,
    loginMutation.data,
    loginMutation.error,
    loginMutation.variables,
    loginMutation.submittedAt,
  ]);

1 Answer 1

0

For me, isSuccess is local to the current component instance. So If you call navigate() in onSuccess, the component unmounts immediately. You never observe isSuccess: true on that instance.

Don’t rely on isSuccess if you navigate or unmount right after the mutation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.