Is Vue js converting nested objects into strings before returning them?

There is an object in my code

   var user = {
      name:"test",
      number:"9666-0503",
      details:{
          test:"cannot_access_this",
          second_field:"nope_no_go"
      }
   }

A call to a Vue JS action is being made

[TYPES.FETCH_USER]({ commit }) {
    api.get('user').then(({ data }) => {
        commit(TYPES.STORE_USER, data)
        console.log(data)
        // The returned data is correct. When accessing nested fields like
        //console.log(data.details.test), I get the expected value
    }, (error) => {
        console.log(error)
    })
},

This is followed by the mutation

[TYPES.STORE_USER](state, data) {
    state.user = data
    localStorage.set("user", state.user)
},

In the getters file

getUser: state => {
    return state.user
}

The Component implements

computed: {
  ...mapGetters(["getUser"]),
},
mounted(){
   this.getData()
},
methods: {
  getData() {
    this.$store.dispatch(TYPES.FETCH_USER);
  }

}

The template shows

    <h1>{{getUser.name}}</h1><!-- this works -->
    <h2>{{getUser.number}}</h2><!-- this works -->
    <h3>{{getUser.details.test}}</h3> <!-- THIS FAILS!!-->

Accessing getUser.details.test fails. However, when just referencing getUser.details, it displays as a string version of the details object:

    <h3>{"test":"cannot_access_this","second_field":"nope_no_go"}</h3>

Why does it stringify nested objects in the template but not in console logs?

Answer №1

Mutations must be synchronous. It's crucial to avoid using asynchronous code in mutations as it can lead to unpredictable behaviors.

The recommended approach is to handle asynchronous tasks in an action, like shown below:

mutations: {
    [TYPES.FETCH_USER](state, data) {
        state.user = data
    }
    //...
},
actions: {
    fetchUsersActionName({ commit }) {
        return api.get('user').then(({ data }) => {
            commit(TYPES.FETCH_USER, data)
            console.log(data)
        }, (error) => {
            console.log(error)
        });
    }
}

When calling this action, use .dispatch() instead of .commit():

this.$store.dispatch('fetchUsersActionName');

Understanding the Error

Take a look at the examples below to understand why you may encounter the error:

<h1>{{getUser.name}}</h1><!-- this works -->
<h2>{{getUser.number}}</h2><!-- this works -->
<h3>{{getUser.details.test}}</h3> <!-- THIS FAILS!!-->

The first example triggers an error because initially getUser.details.test is undefined, resulting in an attempt to access undefined.test, which causes an error:

// JavaScript code snippet omitted for brevity
// HTML script and markup omitted for brevity

To resolve this issue, either implement a conditional check with v-if or initialize the details property within the user object:

// JavaScript code snippets and CSS stylesheets omitted for brevity
// HTML script and markup omitted for brevity

Reason Behind the Error

The error occurs due to the asynchronous nature of the code that updates the user object. When attempting to display properties like {{ getUser.name }} or {{ getUser.number }}, Vue initially shows nothing (as undefined) before updating the values rapidly. However, accessing {{ getUser.details.test }} results in an error because getUser.details is initially undefined, leading to

TypeError: Cannot read property 'test' of undefined
.

Consider implementing the suggested workarounds mentioned above to address this issue effectively.

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

Enhancing bar chart presentation with text in d3

Looking to enhance my bar chart by adding text tooltips that appear when hovering over each bar. While I am a beginner with d3, I've been struggling to implement this feature effectively. Despite trying various methods gleaned from online resources, t ...

What is the best way to distinguish if users are accessing my Facebook app through an iframe or by directly entering the

If my Twitter app url is http://tw.domain.com/ and the app url is http://apps.twitter.com/demoapp/ I need to ensure that users cannot access the application url directly, they must view it within an iframe on Twitter. What method can I use to detect & ...

Is there a workaround for unresolved symlink requirements when using npm link?

Creating an NPM package often involves using the following: npm link This allows for making modifications to a package called <myPackage> during development without constantly having to publish and unpublish! Developers can make changes locally and ...

What causes the variation in size between the next/image and img HTML elements?

Two Images, Different Sizes! https://i.sstatic.net/vpoNG.jpg There seems to be a discrepancy in size between the image rendered by the next/img component and the one displayed using the img element. Interestingly, they both use the same image source and ar ...

Anticipating the resolution of one promise before tackling the next in Angular.js

Is it possible in Angular.js to ensure that a given promise is resolved before another dependent promise? Consider the following code snippet: User.getAllUsers().then(function(users) { $scope.users = users; for (var i = 0; i < users.length; i+ ...

What is the best way to extract the information from the checkbox in a MUI datatable?

I am struggling to transfer an array with checked values to another table in order to display only those values. How can I achieve this? I am relatively new to using react and I find it challenging to grasp how some of the functions and components work. I ...

Utilizing every function across various offspring

Is it possible to use the each function on multiple children at once? The code below shows my attempt to use the each function on both child elements in a single line. $('.right .submission:not(:first)').each(function(){ stud ...

Unable to impose a restriction on the number input field limit

My input field has a type of "number" with the min and max attributes applied to limit user input. However, I am facing an issue where users can still enter values beyond the set limit. How can I prevent users from entering values above the specified lim ...

How can I force an element to overflow without being affected by its parent's overflow style in CSS/HTML/JS, even if the parent is

I've come across many inquiries on this subject, but the proposed solutions never seem to work when dealing with ancestors that have absolute positioning. Take this example: <div id='page'> <div id='container' style= ...

is it possible to dynamically add components within a Vue.js component?

Is there a way to dynamically add components within a component? Note: I do not want these components to be saved globally, but rather added locally. The best way to define the problem is by showing code examples. export default { name: 'tab ...

Utilizing Azure SDK to send an email

In my Node.js project, I am currently utilizing azure-graph: const MsRest = require('ms-rest-azure'); const credentials = await MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId, { tokenAudience: 'graph' } ...

When invoked, a Javascript Object comes back empty

My code snippet: const channels = fauna.paginate(q.Match(q.Index("channels"), "true")) // Query FaunaDB database for channel list => create constant called users containing results const channelList = channels.each(function (page) { ...

Ways to retrieve the content from a textfield

Is there a way to retrieve text from a textfield in material UI without using the onChange method? It just seems odd that I would need to constantly track the value with onChange in order to use it for any other purpose. I decided to search for solutions ...

Guide on utilizing JavaScript to modify the attribute of a chosen web element with Selenium WebDriver in Java

I am seeking a way to utilize Javascript in order to set attributes for the selected element on a webpage. After some research, I have discovered two methods for achieving this with Javascript: Method 1 WebDriver driver; // Assigned elsewhere Jav ...

Is it possible to implement nested views with Angular's built-in ngRoute module (specifically angular-route.js v1.3.15)?

For a project I'm working on, we have decided not to use UI router and are only using ngRoute. I need to create nested views - is it possible to achieve this with just ngRoute without any additional library support? If so, could you please provide a w ...

HTML comment without the presence of javascript

Is it possible to use different expressions besides checking for the browser or version of IE in order to display/hide content? For example: <!--[if 1 == 0]--> This should be hidden <!--[endif]--> I am considering this option because I send o ...

The performance of CasperJS when used with AngularJS is subpar

If I click on just one button in Casper, everything works perfectly. The code below passes the test. casper.then(function() { this.click('#loginB'); this.fill('#loginEmailField', { 'loginEmail': '<a ...

Converting an rrule date value from an array to a customized string format

Here is an array that I am working with: [{ evening_feeding: false evening_feeding_time: "19:00" feeding_frequency_rule: **"FREQ=DAILY;INTERVAL=2"** id: 890 morning_feeding: true morning_feeding_time: "04:00 ...

Executing NodeJS Functions in a Particular Order

Just starting to learn Node and working on building an app. Currently, in my route file, I am attempting to connect to MySQL and retrieve the major of the user, then use it for other operations. However, when I run the webpage, the console displays that t ...

Error: The code is unable to access the '0' property of an undefined variable, but it is functioning properly

I am working with two arrays in my code: bookingHistory: Booking[] = []; currentBookings: any[] = []; Both arrays are populated later in the code. The bookingHistory array consists of instances of Booking, while currentBookings contains arrays of Booking ...