Search code examples
javascriptreactjsaxiosnext.jsnext-redux-wrapper

Updated object not being returned properly in nextjs


So basically I'm working on a nextjs app which uses authentication. I have a 2 functions which I run on every page load. The first checks if jwt cookies exist and calls another function to validate the tokens if they don't exist. This function is ran from wrapper.getServerSideProps and is passed in the context as ctx. This function works as intended.

export const checkServerSideCookie = (ctx) => {
   const access = getCookie("access", ctx.req);
   const refresh = getCookie("refresh", ctx.req);
   if (access && refresh) {
      return checkAuthentication(access, refresh);
   } else return { isAuthenticated: false, token: null };
};

The second function is the token validator and this is where the issue arises. I have an object which I intended to update if the validation is successful and leave alone if it isn't. Here is the function

export const checkAuthentication = (access, refresh) => {
   const obj = {
      isAuthenticated: false,
      token: null,
   };
   const body = JSON.stringify({ token: access });
   axios
      .post("http://localhost:8000/api/jwtoken/verify/", body, {
         headers: {
            "Content-Type": "application/json",
         },
      })
      .then((res) => {
         obj.isAuthenticated = true;
         obj.token = access;
      })
      .catch((err) => {
         // call new token function using refresh
         console.log("it doesnt work");
      });
   return obj;
};

The issue is is that the .then does update the object, and when I console.log(obj) in the .then it shows the proper obj to return, however when I return the obj it still holds the initial values of false and null. I don't understand what the issue is. I try doing the return in the .then itself but it throughs this error TypeError: Cannot destructure property 'isAuthenticated' of 'Object(...)(...)' as it is undefined. What is the issue here? It all seems good but the updated obj isn't returned.


Solution

  • axios.post is async, you're returning the obj before it gets filled with data from the api response, you can use async/await to solve that :

    export const checkAuthentication = async (access, refresh) => {
      const obj = {
        isAuthenticated: false,
        token: null
      };
    
      const body = JSON.stringify({ token: access });
    
      try {
        const res = await axios.post("http://localhost:8000/api/jwtoken/verify/", body, {
          headers: {
            "Content-Type": "application/json"
          }
        });
    
        obj.isAuthenticated = true;
        obj.token = access;
      } catch (e) {
        // do something with the error
        // call new token function using refresh
        console.log("it doesnt work");
      }
    
      return obj;
    };
    

    usage (checkAuthentication now return a promise ) :

    checkAuthentication(a, b).then((obj) => {
      console.log(obj);
    });