Handling a this.$router.replace(href); in vue 2

29 Views Asked by At

I am new to vue and working on vue code those before me created. So there is a lot of legacy code that is just too complex to change right now.

The vue code can be in one of two states when a user wants to navigate to DynamicReport, they might be on that component or might not. The problem I am trying to solve is that when the user is on DynamicReport and the code does a push, it gets the NavigationDuplicated error. I have changed the code to do a replace, but that doesn't fire the mounted handler. So I am trying to figure out how to reinitialize the component when the user wants to navigate to the new report.

This is in the App.vue:

      viewReportNotification: function(report) {
        const { href } = this.$router.resolve({
          name: 'DynamicReportWithId',
          params: { reportResultsId: report.reportResultsId } // Route parameters
        });

        console.log(`this.$route.path: ${this.$route.path}`)
        console.log(`href: ${href}`)
        if (this.$route.path !== href) {
          if (this.$route.path.startsWith('/DynamicReport/')) {
            console.log(`trying to replace: ${href}`)
            this.$router.replace(href);
          } else {
            console.log(`trying to PUSH: ${href}`)
            this.$router.push(href);
          }
        }
      },

And I tried adding this to the component, but the beforeRouteUpdate isn't being called:

  beforeRouteUpdate: function(to, from, next) {
    console.log(`beforeRouteUpdate( ${to}, ${from}, ...)`);
    if (to.type === 'replace') {
      console.log(`replacing ${from} with ${to}`);
      this.loadReportIfQueryParamsExist();
    }
    next();
  },
  mounted: function() {
    this.loadReportIfQueryParamsExist();
    this.handlePanelOpen();
  },

Again, I am new to vue code, I am sure there is a lot better ways to do the whole thing, but... I am just trying to fix a bug, not redesign the whole thing right now.

2

There are 2 best solutions below

0
Sam Carleton On BEST ANSWER

I found a different approach... The mount calls another method, so now viewReportNotification() calls that other method and then calls replace to update the URL. Works like a charm. Thanks for the suggestions, I appreciate it!

0
jesvin palatty On

Since You are trying to kind of navigate to the same page, this issue is happening. What you can do is since you know that you need to push/replace to the same URL, you can try to reload the component so as this will re-run the mounted life cycle (Also since you mentioned legacy I am assuming you are using vue 2)

You can try using ->

vm.$forceUpdate();

Here vm is the Vue instance

Another preferable method would be to componentize the report view and use key and simply change it to re-render the component and this way the child component (here the reports component) will get re-rendered.

<template>
  <report-component :key="componentKey" />
</template>

<script>
export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
    }
  }
}
</script>

Now you can call the forceRerender() method whenever the query changes and thus re-run the mounted method