Home > Software design >  Losing querystring on double click
Losing querystring on double click

Time:11-12

I enter my site through a reverse proxy server that is passing a token to my site. I want to be able to force that token onto the query string every time I go to a different route and I want to be able to do that without putting the query string on every "to" in any button I may have. This way if my users reload the page, they don't lose their token.

I am attempting to do this in my default.vue page so that no matter what page I am on it pushes the query string into the route. The problem I am facing is this works great when the user single clicks a button taking them to the route, however when the button is double clicked the querystring isnt being pushed onto the route.

Here is my default.vue and a snip it of the button that does the page change.

....default.vue.....

  <template>
    <v-app>
    <banner :text="My Banner Text"/>
    <v-container fluid px-0 py-0>
     <v-main>
      <nuxt />
     <v-main>
    </v-container>
    </v-app>
    </template>
    
    <script>
      import banner from '@/components/layouts/default/banner'
      export default {
       components: {
         banner
        }, 
    data() => {
      return {
        landingRoute: null,
      }
     }, 
    async fetch(){
     if(this.isEmpty(this.$route.query)){
      const landingkey = this.landingRoute
      this.$router.push({name: this.$router.name, query: {info: landingKey}})
    },
    watch:{
      '$route.query': '$fetch'
    },
    mounted(){
    this.landingRoute = this.$route.query.info
    }, 
    methods: {
         isEmpty(json){
            return Object.keys(json).length === 0
         }
    }
 }
    </script>

...... mainNav.vue .......

This is the portion that is relevant

<v-btn
   to="/request"
><span>Request</span>
</v-btn>

CodePudding user response:

i think you can handle this using router middleware as it is explained in nuxt document in this case in your nuxt.config.js file you will add middleware property to your router config:

router: {
    // other configs
    middleware: ['landingKey']
}

then you need to create middleware directory in your project root. in this directory create landingKey.js file which contains:

export default function ({ route, redirect, store }) {
    // saving key to store
    if (!store.state.landingKey) {
        store.commit('saveLandingKey', route.query.info)
    }
    // adding info to query if it doesnt exist
    if (!route.query || (route.query && !route.query.info)) {
        return redirect({name: route.name, query: {...route.query, info: store.state.landingKey}})
    }
}

with this solution you wont need to pass landingKey every time and also it will redirect if a route doesnt have landingKey. this all happens before mounting components. also if you need to use this middleware in specific pages and not globally, you can simply use middleware: ['landingKey'] in your page file.

also you can use cookie-universal-nuxt if you dont want to use vuex. so in this case, you have to do something like this:

export default function ({ route, redirect, app }) {
    if (!app.$cookies.get('landing-key')) {
        app.$cookies.set('landing-key', route.query.info, {
            path: '/',
            maxAge: 60 * 60 * 24 * 7
        })
    }
    // adding info to query if it doesnt exist
    if (!route.query || (route.query && !route.query.info)) {
        return redirect({name: route.name, query: {...route.query, info: app.$cookies.get('landing-key')}})
    }
}

CodePudding user response:

The code snippet that you actually shared is pretty messy with a lot of errors. After some ESlint Prettier, this is the result. Give it a try, it could work with just that.

/layouts/default.vue

<template>
  <v-app>
    <banner text="My Banner Text" />
    <v-container class="fluid px-0 py-0">
      <v-main>
        <Nuxt />
      </v-main>
    </v-container>
  </v-app>
</template>

<script>
import banner from '@/components/layouts/default/banner'

export default {
  components: {
    banner,
  },
  data() {
    return {
      landingRoute: null,
    }
  },
  fetch() {
    if (this.isEmpty(this.$route.query)) {
      const landingKey = this.landingRoute
      this.$router.push({
        name: this.$router.name,
        query: { info: landingKey },
      })
    }
  },
  watch: {
    '$route.query': '$fetch',
  },
  mounted() {
    this.landingRoute = this.$route.query.info
  },
  methods: {
    isEmpty(json) {
      return Object.keys(json).length === 0
    },
  },
}
</script>

Then, as I've told you in my comment, try to use the Vue devtools to inspect the events and the state at the same time. To narrow down your issue.

I find the code pretty strange by itself but the issue may probably come from the fact that you do have a mounted that is used to set landingRoute but an actual layout is not re-mounted AFAIR.

So yeah, please do the following steps and I'll do my best to help you if you still have some issues!

  • Related