No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    How to serialize axios functions ?

    Framework
    3
    7
    314
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I
      Incremental last edited by

      Hello, I’m still learning Vue.js and Quasar and I have a problem with my server store.
      I use JWT and have 2 functions using axios : refreshToken() and updateProfile().
      When updating my profile, I want first to refresh my token to ensure my user is still valid.
      My problem is that the updateProfile() is called before the end of the refreshToken() with this code :

      this.$store.dispatch('server/refreshToken');
      
      // SHOULD WAIT refreshToken() END before continue...
      const pwd_data = new URLSearchParams();
      pwd_data.append("user_id", this.Name);
      pwd_data.append("password", this.new_password1);
      this.$store.dispatch('server/changePassword', { data: pwd_data })
      

      my store :

         refreshToken ({ commit }) {
            const authorization = { headers: { 'Authorization': 'Bearer ' + state.token } }
            this.$axios
               .patch(constantes.SERVER_URL + "/api/auth/refresh-token", authorization)
               .then(response => {
                  // status 200 -> "Refreshed" = OK
                  console.log("refreshToken - Response OK : ", response);
               })
               .catch(error => { // Request Failed!
              ....
      

      My updateProfile() has the same structure.
      I tried to use await in the refreshToken() axios call, but it doesn’t wait 'til the result !
      I read many things about promises, but they are always relating to display problems.
      As I just want to serialize my two function calls in my server dialog, how would you do that ?
      Thanks for your help.

      beets 1 Reply Last reply Reply Quote 0
      • beets
        beets @Incremental last edited by

        @Incremental Try to first return a promise from the refreshToken action, like this:

           refreshToken ({ commit }) {
              const authorization = { headers: { 'Authorization': 'Bearer ' + state.token } }
              return this.$axios
                 .patch(constantes.SERVER_URL + "/api/auth/refresh-token", authorization)
        // ...
        

        Notice the returning of the axios call, that will return a promise. Then, like this:

        this.$store.dispatch('server/refreshToken')
        .then(() => {
          // SHOULD WAIT refreshToken() END before continue...
          const pwd_data = new URLSearchParams();
          pwd_data.append("user_id", this.Name);
          pwd_data.append("password", this.new_password1);
          this.$store.dispatch('server/changePassword', { data: pwd_data })
        }).catch(error => {
          // Request failed
        })
        
        1 Reply Last reply Reply Quote 0
        • I
          Incremental last edited by Incremental

          Wow ! Thanks beets for your help, it works.
          Just a complement : how could I retreive error codes for refreshToken() and changePassword() ?
          For some reasons, I get a CORS error in my refreshToken() and a HTTP 500 in changePassword() but nothing is displayed with the following code :

          this.$store.dispatch('server/refreshToken')
          .then(() => {
            // SHOULD WAIT refreshToken() END before continue...
            const pwd_data = new URLSearchParams();
            pwd_data.append("user_id", this.Name);
            pwd_data.append("password", this.new_password1);
            this.$store.dispatch('server/changePassword', { data: pwd_data })
          }).catch(error => {
            // Request failed
            console.log('error.config', error.config);
            console.log("error response : ", error.response);
            console.log('error.message', error.message);
            console.log("error.request : ", error.request);
          })
          
          beets 1 Reply Last reply Reply Quote 0
          • beets
            beets @Incremental last edited by beets

            @Incremental Try something like this:

               refreshToken ({ commit }) {
                  const authorization = { headers: { 'Authorization': 'Bearer ' + state.token } }
                  return this.$axios
                     .patch(constantes.SERVER_URL + "/api/auth/refresh-token", authorization)
                     .then(response => {
                        // status 200 -> "Refreshed" = OK
                        console.log("refreshToken - Response OK : ", response);
                     })
                     .catch(error => { // Request Failed!
                       // do whatever here, but re-throw
                       console.log('Refresh error code: ', error.response.status)
                       throw error
                     })
                }
            

            And

            this.$store.dispatch('server/refreshToken')
            .then(() => {
              // SHOULD WAIT refreshToken() END before continue...
              const pwd_data = new URLSearchParams();
              pwd_data.append("user_id", this.Name);
              pwd_data.append("password", this.new_password1);
              this.$store.dispatch('server/changePassword', { data: pwd_data }).catch(error => {
                console.log('Change password error code: ', error.response.status)
              })
            }).catch(error => {
              // Request failed, but we already caught the error 
              console.log(error)
            })
            
            

            You probably have to change your changePassword action to return the axios promise call like we did with the refresh token one. There’s many ways to skin this cat once you realize how promises / async / errors all work together. You could also just not put a catch block in your actions (make sure you’re returning the axios call still), and do this:

            async someFn() {
              try {
                await this.$store.dispatch('server/refreshToken')
            
                const pwd_data = new URLSearchParams();
                pwd_data.append("user_id", this.Name);
                pwd_data.append("password", this.new_password1);
                await this.$store.dispatch('server/changePassword', { data: pwd_data })
            
              } catch(error) {
                // One of the two requests failed
                console.log('error.config', error.config);
                console.log("error response : ", error.response);
                console.log('error.message', error.message);
                console.log("error.request : ", error.request);
              }
            }
            

            Edit, and if you want to know which of the two actions failed:

            async someFn() {
              try {
                await this.$store.dispatch('server/refreshToken')
              } catch(error) {
                // Refresh requests failed
                console.log('error.config', error.config);
                console.log("error response : ", error.response);
                console.log('error.message', error.message);
                console.log("error.request : ", error.request);
              }
              try {
                const pwd_data = new URLSearchParams();
                pwd_data.append("user_id", this.Name);
                pwd_data.append("password", this.new_password1);
                await this.$store.dispatch('server/changePassword', { data: pwd_data })
              } catch(error) {
                // Change requests failed
                console.log('error.config', error.config);
                console.log("error response : ", error.response);
                console.log('error.message', error.message);
                console.log("error.request : ", error.request);
              }
            
            }
            
            1 Reply Last reply Reply Quote 0
            • I
              Incremental last edited by

              Thanks a lot beets, you really helped me ! 😉

              1 Reply Last reply Reply Quote 0
              • s.molinari
                s.molinari last edited by s.molinari

                I’m just getting into the world of jwt tokens myself, and my understanding of the token flow is, your system should be working between a refresh and an access token (which seems to be missing here) and this “workflow” should be seamless for the app developer. By seamless I mean, either the current user is “logged in” or she isn’t. Every call to the server should have a (short-lived) access token in the request header (ala Authorization Bearer <token>). If the access token is no longer valid (because of ttl) the system should automatically call the refresh endpoint, also sending the refresh token. If it is still valid, then a new access token is given and the app can continue working. If the refresh token is no longer valid, the request for refresh gets an an error in return and the user is logged out. There shouldn’t need to be a checking of the refresh token “manually” in the code ever. There should be a set state for the user. LoggedIn (true or false), which is set at login and only revoked, when the refresh token is stale i.e. with that error from the refresh endpoint.

                Please correct me if I’m wrong. 🙂

                Scott

                1 Reply Last reply Reply Quote 0
                • I
                  Incremental last edited by

                  You’re right, I just found this clear article simpler than the official doc : https://hasura.io/blog/best-practices-of-using-jwt-with-graphql
                  But at the moment, I can’t really test, because there are some bugs with RLuders JWT plugin and CORS…

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post