rametta / rapini

:leafy_green: OpenAPI to React Query (or SWR) & Axios
Apache License 2.0
152 stars 18 forks source link

newbie help #37

Closed cn-johndpope closed 1 year ago

cn-johndpope commented 1 year ago

basically need an example where I can post the body

eg. passing a model in a post. because you're using the definitions as a hook - it's not clear that I can use this dynamically. eg.

// REACT HOOKS here I want to pass in {username,password} const { data, isLoading, isError } = useLogin({username,password});

it seems trivial example - but I need this dynamic - not set once component is instantiated. I'm going to have to revert until I can get clarity here.

rametta commented 1 year ago

Yes that is exactly how mutations work, you are not expected to have the information right away, you pass the dynamic data to the myMutation.mutate(payload) function.

For rapini, you take the mutations from the intiialize, so

const { mutations } = initialize(axios)

// inside component
const myMutation = mutations.useMyMutation()
const onFormSubmit = () => {
  myMutation.mutate({ my dynamic data goes here })
}

hope that helps. The react query mutation docs has more details on that

cn-johndpope commented 1 year ago

that's helpful - thank you but still not clear how to do the straightforward - checking of errors - and if it is an error - show message.

some historic boilerplate code I've used in the past - where ICredential is username / password

async function loginUserClearCookies(credentials: ICredential) {

        console.error("WARNING - deleting existing session details if any...")
        const keys = ['tokenExpiredCount', 'token', 'user'];
        await AsyncStorage.multiRemove(keys);

        const hasInternet = checkConnectivity();
        if (!hasInternet) {
            setErrorMessage('No internet detected...');
            SnackbarHandler.errorToast("No internet...");
            return
        }
        setPreload(true);
        SnackbarHandler.normalToast("Authorising...");

/// HERE I CAN CALL MUTATE - but am I expecting this inside a try / catch ? and then handling error? 
        NocApi.post('/logon', credentials)
            .then(response => {
                if (response.data) {
                    setErrorMessage('');
                    const token = `wa=wsignin1.0&wresult=${encodeURIComponent(
                        response.data
                    )}`;
                    // console.log('token', token);
                    if (token) {
                        Promise.all([
                            setUser(credentials),
                            postTokenForCookie(token), // this will transition ui isAuthenticated -> true -> logged in > and kick off fetchAll once we get cookie
                            setToken(token),
                        ])
                            .then(async (res) => {
                                setPreload(false);
                            })
                            .catch(err => {
                                console.error('err', err);
                                Analytics.trackEvent(err.message);
                                SnackbarHandler.errorToast("🔥  LOGIN FAILED!!!");
                                setPreload(false);
                            });
                    }
                }
            })
            .catch(error => {
                setPreload(false);
                let err = error as AxiosError
                Analytics.trackEvent(err.message)
                if (err.message == "Network Error") {
                    console.error("We cancelled the request!!");
                    SnackbarHandler.errorToast(err.message);
                    return;
                }
                SnackbarHandler.errorToast('Email or Password not correct');
            });
    }

UPDATE

this is some boiler plate code that I'm wrapping around to the typescript librrary / axios spat out by swagger-codegen-cli-3.0.41.jar

java -Xmx1024m -jar swagger-codegen-cli-3.0.41.jar generate -i openapi.yaml -l typescript-axios -o generate --additional-properties npmName=@Flow,npmVersion=0.0.59,private=false


  const handleLogin = async () => {
    setLoading(true);
    setError('');

    try {
      var model:UserLoginModel = {}
      model.userName = username
      model.password = password
      //usePostAuth(model);

      let result = UsersApiFp().postAuth(model);
      console.log("result:",result);
      setLoading(false);
    } catch (e) {
      setLoading(false);
      setError('Invalid username or password');
    }
  };
rametta commented 1 year ago

@cn-johndpope this seems like a general react query mutation question, there are a lot of docs about how to use it here https://tanstack.com/query/v4/docs/react/guides/mutations . You don't need separate states for loading or errors, don't need a try/catch either, it's all built-in to the hook

cn-johndpope commented 1 year ago

ok touche - this example is perfect. Would be better to replace the other one you have which falls short of showcasing finer details. I can see a path forward now - thanks I hit a snag using the tanstak v4 - I'll raise separate ticket.


function App() {
  const mutation = useMutation({
    mutationFn: (newTodo) => {
      return axios.post('/todos', newTodo)
    },
  })

  return (
    <div>
      {mutation.isLoading ? (
        'Adding todo...'
      ) : (
        <>
          {mutation.isError ? (
            <div>An error occurred: {mutation.error.message}</div>
          ) : null}

          {mutation.isSuccess ? <div>Todo added!</div> : null}

          <button
            onClick={() => {
              mutation.mutate({ id: new Date(), title: 'Do Laundry' })
            }}
          >
            Create Todo
          </button>
        </>
      )}
    </div>
  )
}