Reloading Vue router view following a successful AJAX request

Currently, I am working with a Vue Router set up that consists of two components: a list view and a detailed view. The challenge I am facing is when the data is fetched via ajax, the non-router list updates successfully but the router view does not reflect the changes.

I am looking for a solution to communicate with the router view in order to trigger a redraw with the new data. As of now, clicking on an item in the non-router list correctly navigates to the details component, and clicking "show list" navigates back to the list component with the updated data.

If you want to take a closer look at the code, I have prepared a jsFiddle with the relevant snippets here: https://jsfiddle.net/pengman/jkwvphf9/2/ (The ajax call is emulated using setTimeout for demonstration purposes.)

Here is the structure of my HTML:

<div id="app">
Router-view:
  <router-view class="view"></router-view>
  <br>
  Unrouted list: 
  <div class="list-group">
    <router-link v-for="plante in planter" class="list-group-item" :to="{ name: 'plante', params: { nummer: plante.Nummer }}">{{ plante.Navn }} | </router-link>
  </div>
</div>

<template id="plante-listing-template">

        <ul>
            <li v-for="plante in planter">
                {{ plante.Navn }} <router-link :to="{ name: 'plante', params: { nummer: plante.Nummer }}">Vis</router-link>
            </li>
        </ul>
    </template>

    <template id="plante-detail-template">
        <div>
            plant detail template:
            <h3>{{ plante.Navn }}</h3>
            <router-link to="/">Show List</router-link>
        </div>
        <br>
    </template>

And here is the JavaScript code snippet:

var PlanteListing = {
  template: '#plante-listing-template',

  data: function () {
    return {
      planter: this.$parent.planter
    }
  },
  watch: {
    '$route'(to, from) {
      // Need to update data to recalculate
      this.planter = this.$parent.planter;
    },
    'dataloaded'() {
      this.planter = this.$parent.planter;
    }
  }
};  

var PlanteDetail = {
  template: '#plante-detail-template',
  data: function () {
    var parent = this.$parent;
    var nummerFromRoute = this.$route.params.nummer;

    var filtered = this.$parent.planter.filter(function (item) {
      return (item.Nummer == nummerFromRoute) ? item : false;
    });

    return {
      season: filtered[0]
    }
  },
  watch: {
    '$route'(to, from) {
      var nummerFromRoute = this.$route.params.nummer;

      var filtered = this.$parent.planter.filter(function (item) {
        return (item.Nummer == nummerFromRoute) ? item : false;
      });
      this.plante = filtered[0];
    },
  }
};

var router = new VueRouter({
  mode: 'hash',
  base: window.location.href,
  routes: [
    { path: '/', component: PlanteListing },
    { name: 'plante', path: '/:nummer', component: PlanteDetail }
  ]
});

var app = new Vue({
  router,
  data: {
    planter: []
  },
  components: { PlanteListing: PlanteListing },
  methods: {
    getJson: function () {
      var self = this;

      /* Simulation code: */ 
      setTimeout(function(){
        self.planter = [  
          { "Nummer": "0", "Navn": "Bertha Winters" },
          { "Nummer": "1", "Navn": "Jeannie Small" },
          { "Nummer": "2", "Navn": "Mckay Joyner" },
          { "Nummer": "3", "Navn": "Janelle Banks" },
          { "Nummer": "4", "Navn": "Bray Moran" },
          { "Nummer": "5", "Navn": "Hooper Schwartz" }
        ]; 
        console.log('data loaded')
      }, 500);
    }
  },
  created: function () {
    this.getJson();
  }
}).$mount('#app');

Answer №1

It's not ideal for a component to reach outside itself to fetch data (like with this.$parent.planter). Instead, it's better to pass data as props. I've made some changes to your code to reflect this.

Firstly, I've updated your vue-router to the latest version so you can utilize the props argument in routes.

var router = new VueRouter({
  mode: 'hash',
  base: window.location.href,
  routes: [
    { path: '/', component: PlanteListing },
    { name: 'plante', path: '/:nummer', component: PlanteDetail, props: true }
  ]
});

Additionally, since you're using the planter in all routes, I've included it as a property on the router-view.

<router-view class="view" :planter="planter"></router-view>

This streamlines your component routes and provides them with the necessary data as props.

var PlanteListing = {
  template: '#plante-listing-template',
  props:["planter"]
};  

var PlanteDetail = {
  template: '#plante-detail-template',
  props:["planter", "nummer"],
  data: function () {
    var filtered = this.planter.filter(item => item.Nummer == this.nummer);
    return {
      plante: filtered[0]
    }
  }
};

No need to manually refresh the router; Vue automatically handles updates when using props. You can view your adjusted fiddle here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am currently facing a challenge in React Highcharts where I am unable to remove and redraw the graph easily

Having an issue where I can't remove and redraw the chart in my React Highchart project. I've been unable to find a solution for this problem. Here is the code snippet: import { useState, useEffect, useRef } from "react"; import Highch ...

Steps for updating a JSON entry in a Node.js environment

What is the best way to update a JSON value using node.js? I have come across a few examples online, but my situation is a bit more complex. I am able to access the value that needs to be modified var contents = fs.readFileSync("./../../skill.json"); var ...

"Chrome is throwing an unanticipated error for bigpipe.js with an uncaught syntax error related to

I have integrated the bigpipe.js method into my website to display a newsfeed. It functions properly on all browsers except for Google Chrome, where it shows an 'uncaught syntaxerror unexpected token =' error. I need assistance in resolving this ...

Troubleshooting Problem with JQuery Paginate Plugin Alignment

I have implemented jquery ui 1.10.4 on a web application to paginate and display a specific number of items from an ArrayList on a webpage. However, I am facing an issue where the pagination buttons do not adjust their position when the size of the list ch ...

Using AJAX asynchronously in JavaScript commands synchronization

After researching similar questions on SO without finding a satisfactory answer, I encountered an issue with synchronous AJAX calls in my HTML/JavaScript page. Mozilla has deprecated some functionality related to synchronous requests, making it necessary f ...

Prepending a string to the value using Angular's ngOptions

I've been working on creating a custom directive for Angular that includes a label and select element with necessary classes. This is what my directive code looks like: return { restrict: 'E', scope: { text: &a ...

What is the best way to obtain the final visible element using jQuery?

Could you please check out the following link: http://jsfiddle.net/SHfz4/ All of the blue boxes are technically visible, so I can't use the code $('.row .inner .item:visible:last'); as it will always return box 27. Some boxes may not be v ...

What is the method for inserting a clickable link into a data-image line of code using CSS3?

Recently, I delved into the world of CSS and am still getting the hang of it, Below is a snippet of code that I have been working on, <div id='ninja-slider'> <ul> <li> <div data-image="images/md/1.j ...

Convert a JSON object into a new format with a nested hierarchy

The JSON object below is currently formatted as follows: { "id": "jsonid", "attributes": { "personName": { "id": "name1", "group": "1.1" }, "ag ...

Obtaining DOM data following an AJAX request

I am looking to retrieve DOM values from Perl without having to manually use a browser and debugger. These DOM values are populated after an AJAX call, and a sample function for one of these values may look like this: <script language="javascript"> ...

Assign a title property in Vuejs only if the returned data from binding evaluates to true

Just starting out with vuejs and I have a question. How can I set the title based on a value returned from a specific method only if this value is true? Below is my code snippet: <td v-bind="value = getName(id)" :title="value.age" > {{value.na ...

outside vue component access method is not recommended

I am a newcomer to Vue.js and have implemented a comment feature similar to the one described here. However, due to certain constraints, I had to make adjustments. I used a Vue component but encountered an issue where it couldn't access a method insid ...

Clicking on an absolute HTML element will instantly scroll back to the top of the page

Working on a website, I've designed a custom menu that is hidden with 0 opacity and z-index -1. When a button is clicked, the menu will appear on the screen. You can visit to see the site in action. The issue I'm facing is that every time I cl ...

Is it possible for me to utilize jquery and AJAX to invoke a cgi-bin script, and then incorporate a message event to manage Server Sent Event?

I have a cgi-bin program that runs for a long time (3-15 minutes) and I am looking to invoke it using AJAX. While the program is running, I want to receive Server Sent Event data from it and display it on my web page. It's like having a progress monit ...

Having trouble correctly parsing XML data using JavaScript

My input field contains the following XML code: <?xml version="1.0" encoding="utf-8"?> <players timestamp="1536505850"> <player id="0518" name="Eagles, Philadelphia" position="Def" team="PHI" /> <player id="10271" name="Jones, Jul ...

Creating a dynamic div with various paragraphs using only Javascript

My goal is to dynamically generate paragraphs with their respective icons inside individual div elements. For instance, if the service API returns 30 items, I will create 30 div elements with the class "tile". However, if only one item is returned, then I ...

One way to position a sidebar between two divs is to ensure it adjusts seamlessly to the size of the browser window when resized

In my layout, I have two grids: one for the header and one for the footer. In between these two grids, I am using a sidebar on the left side. Below is the JavaScript code I am using: function adjustSize() { var heights = window.innerHeight; docum ...

The differences between getElementById and getElementByClassName

When using both getElementById and getElementByClassName, I have noticed that getElementById sometimes returns null while getElementByClassName works without any issues. I wonder what might be causing this discrepancy. It is my understanding that getElemen ...

Using Threejs JSONLoader and OOP to easily add models to a scene post-loading

I am working on incorporating the THREE JSONLoader into a "Scenemanager" Object that manages the addition and removal of objects and models. My main goal is to deepen my understanding of OOP, JS, and Threejs. Within App3D (which oversees the scene), I cal ...

Converting an unbroken series of string values into organized key-value pairs for easy reference

I assure you this is not a duplicated question. Despite my attempts with JSON.parse(), it seems to be ineffective. Here's the issue at hand: I recently received assistance from an answer that was both crucial and enlightening. However, the code prov ...