1
votes

I have a page that has a router-view component in it. I also have a button in the parent page that when I click it I perform a router.push() and send in some objects to a named route via params. It works great. However if a user clicks F5 to do a page refresh I am no longer able to obviously send in the necessary object to the my named route because I can't capture the page refresh. I've debugged it and the named route component gets mounted before my parent page is mounted and there doesn't seem to be any way to notify the component in my route of the objects it needs from the parent. Is it that routes are not expected to be tightly coupled to the parent component? Thanks.

   -- Parent component --

<button v-on:click="buttonClick">Get Tests</button>

<router-view></router-view>

...

    
const router = new VueRouter({
  mode: history,
  routes: [ 
    {
     path: "/school/:id/tests",
     name: "tests",
     component: testcomp,
     props: true
    }] 
});

new Vue ({
  router,
  methods: {
    buttonClick: function()
    {
      // ajax call to get tests

      // promise return
      .then( ret =>
      {
        router.push(
        {
          name: "tests",
          params: {
            allTests: ret.tests,
            id: 99,
          }
        });
      })
    },
  },
});

-- Child component --

...

props : {
  allTests: []
},

mounted: function()
{
  // fill in table with this.allTests
}
2
How are you sending the object is it via props? If you could provide a code sample of what you've done it will be great.Jonathan Akwetey Okine
i assumed you have userId param for your route e.g users/:id ? As the route can refresh to fetch data according object that has same userID? And vue-router has location history mode to be enabled, so nothing wrong for my side of featching data even page refresh.SC Kim
@JonathanAkweteyOkine I added some simplified codeCraig

2 Answers

2
votes

From the code snippet, I think what is happening is you're making an ajax request, and based on the returned promise value you pass that as param after a click event. Refreshing page is not going to call the buttonClick function to get you the params. What you should do is to use vue navigation guards beforeRouteEnter guards to achieve your purpose. You can use this guard to fetch your data before the component is created. I will suggest you refactor your code to this if possible.

 <router-link
  tag="button"
   :to="{
   name: 'tests',
   params: { id: 99},
   }"
 >

In the child component, you can use the beforeRouteEnter guard to make your ajax request. Remember here this is not available.

 async beforeRouteEnter(to, from, next) {
 const id= to.params.id;
 if (!id) {
  next("/404");
}
try {
  //example ajax resquest
 const response = await axios.get('/users/' + id)
  next((vm) => vm.setData(response));
} catch (error) {
  console.log(error);
  }
},

So here, we make our ajax request and set the response in the next callback by calling the setData method.

So in our methods, we create the setData function.

methods: {
    setData(response){
     console.log(response)
     // here you have the response and access to this. so you can fill the table with the 
      data here
   }
}

You can read more about the beforeRouteEnter guard here

0
votes

The way this needed to be handled was to not push routes based on something the parent has to do asynchronously. Data that is specific to the child component (the one in the route) needs to be the one responsible for it's lookups. The child component should only need basic information that can be handled in the url params. I'm coming from Angular and the ng-router pattern if I remember correctly allowed you to push anything into a route at the time of declaration of the route. The routes were declared from within the parent component and not outside of it like vue does. Anyway this is how I handled this problem.