Challenges with Vuex and updating arrays using axios

I am currently facing a challenge with VueJS Vuex and Axios:

The issue arises when I retrieve an array with Axios and loop through it to populate its children this way: "Rubriques" has many self-relations, so one rubrique can have multiple child rubriques

ACTIONS :

  actions: {
    get_main_rubriques: ({ commit }) => {
      axios.get('http://localhost:8180/unv-api/rubrique/search/rsql?query=niveau==1')
        .then(resp => {
          let results = resp.data._embedded.rubriques
          results.forEach(element => {
            axios.get('http://localhost:8180/unv-api/rubrique/search/rsql?query=idpere==' + element.id)
              .then((result) => {
                element.childs = result.data._embedded.rubriques
              })
              .catch((err) => {
                console.log(err)
              })
          })
          console.log(results)
          commit('MUTE_MAIN_RUBRIQUES', results)
        })
        .catch(err => {
          console.log(err)
        })
    }
  }

Mutations :

MUTE_MAIN_RUBRIQUES: (state, rubrique) => {
      state.rubriques = rubrique
    }

APP.VUE

computed: {
    ...mapState([
      'rubriques'
    ])
  },
  created: function () {
    this.$store.dispatch('get_main_rubriques')
  }

<b-dropdown v-for="item in rubriques" :key="item.id" v-bind:text="item.libelle" id="ddown1" class="m-md-1">
       <b-dropdown-item-button v-for="child in item.childs" :key="child.id" v-bind:text="child.libelle">
         {{ child.id }} - {{ child.libelle }}
       </b-dropdown-item-button>
</b-dropdown>

The issue I'm experiencing is that the parent dropdowns display correctly, but the child dropdowns do not. They are also not present in the state, although they are logged in the console before the action's commit.

Could anyone point out what I might be doing wrong? Thanks.

Answer №1

Shift

commit('MUTE_MAIN_RUBRIQUES', results)
to be placed within the inner then block, ensuring it is executed after receiving the response:

  actions: {
    get_main_rubriques: ({ commit }) => {
      axios.get('http://localhost:8180/unv-api/rubrique/search/rsql?query=niveau==1')
        .then(resp => {
          let results = resp.data._embedded.rubriques
          results.forEach(element => {
            axios.get('http://localhost:8180/unv-api/rubrique/search/rsql?query=idpere==' + element.id)
              .then((result) => {
                element.childs = result.data._embedded.rubriques;
                console.log(results);
                commit('MUTE_MAIN_RUBRIQUES', results);
              })
              .catch((err) => {
                console.log(err)
              })
          })
        })
        .catch(err => {
          console.log(err)
        })
    }
  }

To comprehend why your approach is not effective, delve deeper into promises and asynchronous operations.

Answer №2

The issue at hand lies in the fact that computed properties lack deep watching capabilities, as explained in this discussion on triggering computed properties related to arrays.

Consider this segment of code:

computed: {
  ...mapState([
    'rubriques'
  ])
}

In this snippet, the parent array rubriques is being watched, but not its child properties like childs.

While observing the console, you may notice a 'just now' update indication, suggesting the values have already been updated when inspected - however, this might not be the case when commit() is executed.

As a result, the parents are added and child fetches continue to run, gradually connecting children to their respective parents within the store.

An approach to address this is by implementing a deep watcher utilizing $forceUpdate() to trigger DOM re-renders.

watch: {
  rubriques: {
    handler: function (after, before) {
      this.$forceUpdate()
    },
    deep: true,
  }
}

@Efrat's solution might serve as a more efficient alternative - waiting for all child data prior to storing parent entries, thus necessitating only one DOM refresh and reducing overall code complexity.

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

Transmit data from a child component to a Vue JS page through props, and trigger the @blur/@focus function to access the prop from the parent component

Seeking guidance on working with props in Vue JS. As a newcomer to Vue, I hope that my question is clear. I've included my code snippet below, but it isn't functioning correctly due to missing Vue files. In my attempt to use a prop created in t ...

Angular constantly looping due to $watchCollection being triggered repeatedly

I am interested in monitoring the changes of an object, referred to as x, specifically its properties which are checkboxes. When a user checks a box, it alters the checked property (prop1) to 1. Each property contains certain content, and when enabled, it ...

Having trouble accessing PDF files on Electron framework

Despite following the advice provided in similar questions' answers, such as including webPreferences: { plugins: true } in the options when creating a BrowserWindow instance, I am still encountering issues. Every attempt to open or view a PDF ...

Using VueJs to associate boolean values with dropdowns

I am currently working on a form with a dropdown menu containing two options: "True" and "False". My goal is to save the selected value as a boolean in the form. For instance, when the user selects "True", I want the value stored as true in boolean format ...

Creating redirects following an axios post request utilizing express

I seem to be encountering an issue with redirects not working properly after receiving a post request via Axios. I've confirmed that the request is sent and that it receives some response from the '/' route, as my console logs show "index" a ...

When attempting to navigate to a different page in Next.js, the Cypress visit functionality may not function as

In my upcoming application, there are two main pages: Login and Cars. On the Cars page, users can click on a specific car to view more details about it. The URL format is as follows: /cars for the general cars page and /cars/car-id for the individual car p ...

Tips for handling Ajax urlencode in PHP

I'm facing an issue with a problem and need some assistance to resolve it. Currently, I am attempting to utilize Ajax urlencode in PHP, but the POST content is not being displayed by PHP as expected when HTML is sent directly to PHP. The following c ...

Fetching a JSON object from an external URL using JavaScript

Currently, I am working on a project using JavaScript and have an API that provides me with a JSON Object. You can access this JSON object by clicking on the following link: . Within this JSON object, there is a specific element located at JSONOBJECT.posi ...

What are the steps to resolve the issue "Error: no valid exports main found" specifically on a Windows 7 operating system?

I've been encountering an issue while attempting to run my react app on Windows 7 OS. I have npm version 6.13.4 and node version 13.6.0 installed on my system. Every time I try to start the application using npm start, I receive the following error co ...

Error: The 'length' property cannot be searched for using the 'in' operator

Hmm, I keep getting an error that says "Uncaught TypeError: Cannot use 'in' operator to search for 'length' in" Every time I attempt a $.each on this JSON object: {"type":"Anuncio","textos":["Probando ...

The selected attribute does not function properly with the <option> tag in Angular

Currently, I am faced with a challenge involving dropdowns and select2. My task is to edit a product, which includes selecting a category that corresponds to the product. However, when I open the modal, the selected group/category is not displayed in the d ...

Typescript is throwing a fit over namespaces

My development environment consists of node v6.8.0, TypeScript v2.0.3, gulp v3.9.1, and gulp-typescript v3.0.2. However, I encounter an error when building with gulp. Below is the code snippet that is causing the issue: /// <reference path="../_all.d. ...

Can you provide instructions on how to display data in two lines within a mat-select field?

Is it possible to show selected options in mat-select with long strings in two lines within the same dropdown? Currently, the string appears incomplete. You can see an example of this issue here: incomplete string example <mat-form-field class="f ...

How to create a dynamic rectangle using mouse movements in VUE with Konva

In Vue.js, I am aiming to achieve a certain behavior. To illustrate my point, here is the Js fiddle example that I am currently working on: https://jsfiddle.net/richardcwc/ukqhf54k/ //Canvas var canvas = document.getElementById('canvas'); var ct ...

Leverage information extracted from the Node.js function

As I dive into the world of NodeJS, a particular issue arose while working with the getCurrentWeather() function. It's asynchronous nature means that it loads instantly upon app start and writes data to variables. However, when attempting to use these ...

Loading individual components and directives in Nuxt.js with Bootstrap-Vue

I've been exploring the integration of Bootstrap-Vue library with my Nuxt.js project. Although I referred to the official documentation for guidance, I encountered an issue. While importing bt-vue as a single module was successful, I wanted to optimiz ...

I can't seem to figure out why I keep encountering a runtime error whenever I attempt to create a basic route in the latest version of nextjs, version 13.5

Encountering an error while attempting to create a basic route in app/dashboard/page.tsx. The error message suggests that the contents are not a valid react component, even though they conform to valid react component syntax. Unhandled Runtime Error Erro ...

Menus that mimic the style of Google Translate's select options

I'm looking to design an HTML select menu using CSS in a similar fashion to Google Translate's style on Google Translate. I've searched for tutorials online, but they all involve jQuery. Is there a way to achieve something similar using only ...

Is it possible to halt component rendering with Composition in VueJS?

In my component, I have been using a computed property along with a v-if statement to prevent it from rendering if certain basic props were not provided. For example: <template> <div v-if="basicPropsProvided"> Blabla </di ...

Creating an interactive table with the power of FPDF and PHP

I have developed a unique Invoice System that allows users to customize the number of headings and fields using FPDF in conjunction with PHP. Subsequently, I can input the heading names and field values into HTML input fields. However, I am encountering a ...