Sending state information through props in a Vuex environment

One of the challenges I am facing is how to make a reusable component that can display data from the store. My idea is to pass the name of the store module and property name through props, as shown below:

<thingy module="module1" section="person">

Inside the component:

<template>
  <h2>{{ title }}</h2>
  <p>{{ message }}</p>
</template>

<script>
import { mapState } from 'vuex';
import get from 'lodash.get';

export default {
  props: [
    'module',
    'section',
  ],
  computed: mapState(this.module, {
    title: state => get(state, `${this.section}.title`),
    message: state => get(state, `${this.section}.message`),
  })
}
</script>

The issue I'm encountering is that the props are undefined when mapState() runs. If I manually set the prop values, the component works fine. When checking the props in the created() hook, they show the correct values. It seems like there might be a race condition happening.

Could it be that I am approaching this problem in the wrong way?

Update

In order to properly access the module namespace within the mapping function, it needs to be passed as part of the computed object, like so:

computed: mapState({
  title() {
    return get(this.$store.state, `${this.module}.${this.section}.title`);
  },
  message() {
    return get(this.$store.state, `${this.module}.${this.section}.message`);
  }
})

(please note that get() is a lodash function, not a vue method)

This logic can also be moved into a mixin for further abstraction.

Answer №1

In the mapState example, it is noted to use a normal function when accessing local state with `this`:

// to access local state with `this`, a normal function must be used
countPlusLocalState (state) {
  return state.count + this.localCount
}

The usage of arrow functions is highlighted in your implementation.

Regarding this.module, it seems that using the binding helper notation may not work as expected. Instead, you may need to explicitly reference the module in the definitions. This could potentially look like:

computed: mapState(this.module, {
  title(state) {
    return get(`${state}.${this.module}`, `${this.section}.title`);
  },
  message(state) {
    return get(`${state}.${this.module}`, `${this.section}.message`);
  }
})

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

"Executing a query on Angular Firestore using the where clause fetches all documents from the

I am encountering a perplexing issue with my angular app that is connected to Firestore. Despite following the documentation closely, when I query for documents in a collection based on a specific condition, the array returned contains every single documen ...

Is there a way to verify the presence of a service worker on a specific URL?

Is there a way for me to determine if external websites have a 'service-worker' or not? Here is what I think could work: Extract all the JavaScript files from the given URL Look for the string 'sw.js' (I am not entirely sure how to ...

Encounter a 401 error code while attempting to fetch data from CouchDB using an AJAX request

I attempted to make an AJAX call in a JavaScript file to fetch data from CouchDB. Unfortunately, I encountered a 401 error message: Failed to load resource: the server responded with a status of 401 (Unauthorized) This is an extract of my JavaScript cod ...

Mysterious sayings encircling the words fetched through ajax

If the localhost is pointing to the folder named www, where the structure looks like: www/ file/test.cpp index.html I want to dynamically load the content of test.cpp into index.html and display it with the help of highlight.js. Below is the cod ...

margin-top: automatic adjustment, with a minimum of 50 pixels

I am trying to add a minimum of 50px margin to the top of my footer tag using CSS, but I haven't been successful with the min() function. I'm not sure if I am overlooking something or if there is another correct approach to achieve this. * { ...

The functionalities of $scope and this in AngularJS

Currently, I am developing a small application using angularjs. In this project, I am trying to implement a feature that involves deleting a contact. The functionality itself works perfectly fine, however, I am encountering an issue where the 'this.op ...

Is there a way to trigger a Tab key click event while typing in a text field?

Can you show me how to capture the Tab key event in jQuery? I want to display an alert if a user clicks the Tab key while entering text in an input field. I have tried using the following code but it's not working... var myInput = document.getEleme ...

What is the best way to retrieve the current state from a different component?

My goal is to access a user set in another component. I passed the state from the highest component (which is the app) by utilizing this function for state change. handleRegisterSubmit(e, username, password) { e.preventDefault(); axios.post('/au ...

Creating a basic popup with jQuery: A step-by-step guide

Currently in the process of creating a webpage. Wondering how to create a popup window with an email label and text box when clicking on the mail div? ...

Dealing with errors in Node.js using the Express framework and the

The code I'm having trouble with is shown below app.get('/', function(req, res, next) { if (id==8) { res.send('0e'); } else { next(); } }); app.use(function(err, req, res, next){ res.send(500, ' ...

AngularJS restricts the display of elements to only 4 using the limitTo filter

I'm facing an issue with my filters. I have a JSON dataset that I need to display on my website, but I only want to show 4 elements that meet a certain criteria. Here's the code snippet: <div ng-repeat="place in places | limitTo: 4 | filter: ...

There was an error in the syntax: a semicolon is missing before the statement

During an ajax request, I encountered this error and upon reviewing it thoroughly, I am unable to pinpoint the cause. The following code snippet is where the issue seems to lie: $('#post_submit').click(function() { var poster_id = <?php echo ...

creation of cascading drop-down lists

I have been struggling to create a dependent dropdown list using ajax and php, but unfortunately I am not getting the desired outcome. Below is my ajax code: <html> <head> <title>findperson</title> <script type="text/javascript ...

Activate the Click in the Span Element with no Matching ID to the Final Segment of the URL

I'm facing an issue with triggering the click event on a specific span that lacks an id attribute. This particular span has an empty ID and doesn't respond when I try to click the back or forward buttons in the browser. All other spans trigger th ...

Issue with Angular: boolean value remains unchanged

Currently, I'm encountering an issue with my application. My objective is to establish a list containing checkboxes that toggle their values between true and false when clicked. Sounds simple enough, right? Below is the HTML code snippet: <l ...

Guide to implementing CSS3 transitions with prefixes using JavaScript

Is there a way to apply CSS styles using JavaScript when I don't have access to the CSS file? #fade div { -webkit-transition: opacity 1s; -moz-transition: opacity 1s; -o-transition: opacity 1s; -ms-transition: opacity 1s; transition: ...

Is there a way to deliver information to a specific element on a client's HTML page?

My current project involves using Node.js to serve a webpage that collects user inputs and stores them in a mongodb server. The web page also displays these user inputs. I am trying to determine the best way to pass the user inputs from node.js to the < ...

Encountering an error in resolving symbol values statically within the Angular module

Following a helpful guide, I have created the module below: @NgModule({ // ... }) export class MatchMediaModule { private static forRootHasAlreadyBeenCalled: boolean = false; // This method ensures that the providers of the feature module ar ...

Creating a button that integrates an image within a single div element

Currently, I understand the code: $('#leftDev').css("background-image", "url(img/1.png) "); will set the entire background of my leftDiv to display "1.png". However, I would like to position this image as a regular picture within the div and no ...

Is there a way to manually stop a file upload (stream) using a XMLHttpRequest on the server?

Utilizing XMLHttpRequest (Level 2) to transfer a file to a node.js server, I am currently examining the file-stream for valid headers on the server side. The goal now is to halt the upload if any errors are encountered during streaming. My XMLHttpRequest c ...