Upgrading object based on dynamic data shifts in Vue using Vuex

My current task involves updating data in a component based on the selection made from a tabs list at the top of the page. The data is sourced from a Vuex data store, and after conducting tests on the data store, everything appears to be functioning correctly. I have inserted dummy data into the data store which is visible in my Vue Chrome dev tools plugin.

However, upon structuring the component as outlined below and attempting to load the page, an error message

Cannot read property 'amount' of undefined
is displayed in the console. It seems like this issue arises because the data loads before the computed properties are set in Vue.

I am contemplating various approaches but am aiming to seamlessly switch the displayed data when a tab is selected. One option would involve creating a separate component for each tab, although this could lead to redundant code.


Previous Attempts

- I attempted replacing currentObj: this.obj1 with currentObj: {} in the data section, but encountered the same error.

- Moving the currentObj data property to a computed property was another approach. While this allowed the page to load, the error persisted, and selecting tabs did not update the data.


Is there a method to effectively swap out the data in currentObj within my component?

<template>
  <div>
    <ul class="tabs">
      <li class="tab-title" v-on:click="tabSelection = 'tab1'">Tab 1</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab2'">Tab 2</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab3'">Tab 3</li>
    </ul>
    <div>{{ currentObj.amount }}</div>
  </div>
<template>

<script>
export default {
  data: function() {
    return {
      tabSelection: 'tab1',
      currentObj: this.obj1
    }
  },
  watch: {
    tabSelection: function(oldTabSelection, newTabSelection) {
      switch (newTabSelection) {
        case 'tab1':
          this.currentObj = this.obj1;
          break;
        case 'tab2':
          this.currentObj = this.obj2;
          break;
        case 'tab3':
          this.currentObj = this.obj3;
          break;
      }
    }
  },
  computed: {
    obj1: function() {
      return this.$store.getters.obj1;
    },
    obj2: function() {
      return this.$store.getters.obj2;
    },
    obj3: function() {
      return this.$store.getters.obj3;
    }
  }
}
</script>

Answer №1

My suggestion is to update your template for safer navigation:

<template>
  <div>
    ...
    <div>{{ currentObj && currentObj.amount }}</div>
  </div>
<template>

Alternatively, you can also try:

<template>
  <div>
    ...
    <div v-if="currentObj">{{ currentObj.amount }}</div>
  </div>
<template>

Answer №2

One issue arises when currentObj becomes undefined unexpectedly. To address this symptom, we can follow the solution proposed in another response which suggests handling scenarios where obj1, and similar objects, may be missing from the store. This situation occurs if these objects are not defined at the time a tab is clicked:

An attempt was made to substitute data's currentObj: this.obj1 with currentObj: {}. However, the error persists.

Furthermore, even if obj1, etc. are present in the store, the obj1 computed property might still not be accessible in data due to the component instance being yet to be created as it depends on existing data. The lifecycles between beforeCreate and created need to run first.

A workaround entails invoking a getter:

currentObj: this.$options.computed.getNumbers.call(this)

Naturally, this may lead to complications if the computed property relies on other unavailable elements. A more appropriate approach involves explicitly defining initial data:

currentObj: this.$store.getters.obj1

To avoid such issues altogether, the component should be designed differently so that there are no problems. Removing the need for a tabSelection watcher and making currentObj a computed property instead of data would be better since its value is determined based on tabSelection:

  computed: {
    currentObj() {
      let obj;
      switch (this.tabSelection) {
        case 'tab1':
          obj = this.obj1;
          break;
        case 'tab2':
          obj = this.obj2;
          break;
        case 'tab3':
          obj = this.obj3;
          break;
      }
      return obj || { amount: 'No amount' } // in case missing objs are expected
    },
    ...

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

Using JSP to send variables from an external Javascript file

After creating a timer function, I am looking to display the results on a different page. The setup involves a JSP file calling functions from a separate JS file in order to output the information to another screen: Instructions in the JSP file: <butt ...

What is preventing the control from being passed back from the PHP file to the AJAX success function?

My website is built using PHP, Javascript, and AJAX. Below is the essential code snippet: JS code (AJAX function): $("#btn_add_event").click(function(){ var strSeriaze = $( "#formAddEvent" ).serialize(); url = $( "#formAddEvent" ).attr('act ...

Encountering an unforeseen issue with the config.kit.methodOverride while executing Svelte

While working on a Svelte project, I recently updated it to the latest version using the migration tools provided. However, now the project doesn't seem to interact with npm as expected. When I run npm i, it installs the node modules but throws an er ...

What is the best way to apply the TableRow style in material-ui / mui to make it similar to TableHead?

Trying to implement TableHead styling on TableRow but encountering a warning: validateDOMNesting(...) cannot be a child of. How can this be fixed without triggering a warning message? CollapisbleTableRow.js import React, { Fragment, useCallback } from &ap ...

Obtaining targeted information from JSON using JavaScript

Extracting specific data from a JSON object can be challenging, especially if you are new to JavaScript. Below is an example of JSON data containing various fields: {"Date":"2021-01-31........ to ....10.9,"windDir":"SSE"} ...

Tips for resolving the issue of 'no serverless pages built' during deployment of a Next.js application on Vercel

Recently, I've been encountering the same two errors while trying to deploy my NextJs app: // and will just error later on Error: No serverless pages were built. You can learn more about this error here I'm stuck and unsure of how to resolve bo ...

Troubleshooting: Vite fails to execute "npm run build" with Vue3

I am encountering an issue with my Vue3 project where it runs smoothly on development using npm run dev. However, when I try to build it using npm run build, the process fails: C:\projects-intellij\myapp> npm run build > <a href="/cdn-c ...

Issue with PHP retrieving initial value of post data

Hi there, I am facing an issue with my PHP code where the first value of the input field is not being displayed. However, when I check the console.log, it shows correctly. Here is my console.log output: PHP Output: function summary() { $(document).re ...

What is preventing this AJAX request from redirecting to the `/login` URL?

I'm currently developing a Node Express application with Handlebars. Although I receive a success message in the console, the URL doesn't change to /login, preventing the page from rendering. However, manually entering the URL localhost:3000/log ...

What is the best way to connect DataTable() to an already existing HTML <table> by utilizing Vue.js and populating it with data from an array using a v-for loop

Having trouble implementing DataTable features like search field and column sorting in Vue.js for my table. I have included the original datatable.min.js in the <head> section, and also added and called another custom.js file with the following cont ...

Restrict the character count in the input field according to its width

Is there a way to restrict the number of characters in an input field based on its width? I have a dynamic input field with varying widths and I would like users to be able to type without their text extending outside of the input boundary. Using maxLeng ...

"In the shadows, the .toLowerCase() method of undefined is failing without making a sound, yet the code

It seems that letting things fail in the background is necessary for this example to work consistently. Is there a way to work around this issue? There are instances where I need to check a div with a data-attribute on certain pages and add a class if it ...

Having issues with utilizing $fetchState in Nuxt 2.12

Recently, I've been exploring the new functionality outlined in the documentation. However, I'm encountering an error that states : Property or method "$fetchState" is not defined on the instance but referenced during render. Despite clearly ...

Learn how to bypass the problem of self-signed certificates in request-promise

In my node application, I am utilizing the request-promise module to make API calls. You can find more information about it here. import request from 'request-promise'; let options = { method: GET, json: true, ...

What steps can I take to ensure that when the user clicks the logout button, they are redirected to the home component?

Struggling to find a way to direct the user back to the Home component after logging out. The API functionality has been tested and is working properly. I'm unsure how to properly implement the logout method in the current context to allow for succes ...

Using vanilla JavaScript in a node.js environment alongside Functional Reactive Programming (FRP) with bacon.js

I am interested in incorporating Functional Reactive Programming (FRP) into my project. I have come across a popular library for node.js called bacon.js that implements FRP. However, I am having trouble finding examples of how to use bacon.js in native J ...

The trick to keeping a div open without it closing until the page is refreshed

I am currently working on a project that involves creating an interactive map with dots. Each dot, when clicked, should trigger the display of a form related to that specific dot within a <div>. My challenge is ensuring that once a dot is clicked an ...

What is the best way to display a default image in a kendo grid when the image field is empty?

I am trying to display a default image if the image field is empty. Below is the code for the image field: { field: "Photo", title: "Photo", template: '<img src="#= Photo ? Photo : 'default.jpg' #" alt="image" width="80px" height="80px" ...

Looking to transform a list into JSON format using JavaScript?

I have a collection that looks like this: <ol class="BasketballPlayers"> <li id="1">Player: LeBron, TotalPoints: 28753, MVP: true</li> <li id="2">Player: Steph, TotalPoints: 17670, MVP: true< ...

Tips for bringing in an npm package in JavaScript stimulus

Looking to utilize the imageToZ64() function within the zpl-image module. After installing it with: npm install zpl-image I attempted importing it using: import './../../../node_modules/zpl-image'; However, when trying to use the function like ...