Utilizing the nuxt $store in a Dynamic Component

I'm currently working on a Promise-based modal component that allows for specifying a component as the body of the modal itself. My approach to achieving this was by using a dynamic component inside the modal template. However, when working within a NUXT application, I encountered an issue where referencing the Vuex instance (this.$store) resulted in it being undefined. The same problem occurred with any injections made inside plugins, leading to undefined attributes like $api. If the component is used in a 'standard' way—such as placing it directly inside a page or another component template—everything works fine.

It seems there might be some additional injection steps required before passing the component programmatically. Can anyone offer assistance?

The simplified structure of the NUXT project:

  • /pages/index.vue
  • /plugins/api.js
  • /store/auth.js
  • /components/HelloComponent.vue

/plugins/api.js

let api = {}

api.call = function (request, auth, unpack, axios = this.axios) {
  if (!request) Error('backend.js:call invalid params:', request, auth, unpack, axios)

  if (auth) {
    if (request.headers)
      request.headers['Authorization'] = 'Bearer ' + this.auth.accessToken
    else
      request.headers = { 'Authorization': 'Bearer ' + this.auth.accessToken }
  }
  return axios(request).then((response) => unpack ? response.data : response)
}

api.getAPI = function (api, params, auth = true, unpack = true) {
  if (!api) Error('api.js:getAPI invalid params:', api)
  console.log('api.js:getAPI api:', api)
  return this.call({ method: 'get', url: api, params: params }, auth, unpack)
}

api.postAPI = function (api, params, data, auth = true, unpack = true) {
  if (!api) Error('api.js:postAPI invalid params:', api, data)
  console.log('api.js:postAPI api:', api)
  return this.call({ method: 'post', url: api, params: params, data: data }, auth, unpack)
}


/*******************************************************/
/*         NUXT plugin and reference injection         */
/*******************************************************/

export default function (context, inject) {

  console.log('[CALL] api.js')

  /* assign global $axios instance */
  api.axios = context.$axios

  /* assign auth instance to access tokens */
  api.auth = context.store.state.auth

  /* inject backend reference into application instance */
  inject('api', api)
}

/pages/index.vue

<template>
  <div>
  
    <span>
      {{ $store.auth.state.name }} // -> Displays 'Chuck'
    </span>
    
    /* Object.keys(this).includes('$store): false'; Object.keys(this).includes('$auth): true' */
    <component :is="cComponent" /> // -> this.$store is undefined; auth: undefined
    
    <hello-component /> // -> Displays 'Chuck'; auth: Object {...}
  </div>
</template>

<script>
import HelloComponent from '../components/HelloComponent.vue'
export default {

  components: {
    HelloComponent
  },
  
  created () {
    this.$store.commit('auth/setName', 'Chuck')
  },
   
  computed: {
    cComponent () {
      return HelloComponent
    }
  }
}
</script>

/components/HelloComponent.vue

<template>
  <span>
    {{ $store.auth.state.name }}
  </span>
</template>

<script>
export default {

  created() {
    console.log('auth:', this.$auth)
  }
  
}
</script>

/store/auth.js

export const state = () => ({
  accessToken: null,
  refreshToken: null,
  name: null,
})

export const mutations = {

  setAccessToken(state, token) {
    console.info('auth.js:setAccessToken', token)
    state.accessToken = token
  },

  setRefreshToken(state, token) {
    console.info('auth.js:setRefreshToken', token)
    state.refreshToken = token
  },

  setName(state, name) {
    console.info('auth.js:setName', name)
    state.user = name
  },

}

Answer №1

If you find yourself without access to the this pointer in your Nuxt project but still need to reach the store, a simple solution is to utilize

window.$nuxt.$store rather than this.$store;

This workaround should help resolve any issues you encounter.

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

A step-by-step guide on how to insert an image URL into the src attribute using the

The source of my image is -> src/assets/images/doctor1.jpg I would like to use this image here -> src/components/docNotes/docNotes.js In the docNotes.js file, I attempted -> <Avatar className={classes.avtar} alt="Remy Sharp" src ...

Picking and modifying a newly added HTML input element using Jquery

I am encountering a problem that I haven't been able to find a solution for through research or Google. I managed to successfully add multiple input boxes to my HTML/JQuery project, which are displaying correctly on the webpage. for (i = 0; i < ma ...

Display a loading screen in ExpressJS until the data is fully loaded and ready for use

I am currently utilizing puppeteer to extract data from a job website, and so far everything is running smoothly. app.get('/', async (req, res) => { res.render('index', {text: 'This is the index page'}); }) Up ...

Issues with reading response headers in AngularJS when using Apiary.IO?

I am attempting to mock my API using Apiary.io, but I am facing an issue where I cannot retrieve any headers from the response object in angularJS. I have verified that at least Content-Type: application/json is correctly set up by checking in firebug. The ...

Filter Angular by columns that change dynamically

I have a filter function that works well when I use a static column name like this: this.listOfData = this.listOfData.filter((item: DataItem) => item.name.toLowerCase().indexOf(newValue.toLowerCase()) !== -1 ); Note: item.name However, I need to sea ...

What is the best way to combine an array into a single string and insert it into a textarea with line breaks?

My current goal involves executing the following code with no success: var arr = ['one', 'two','three'] const mydiv = document.createElement('textarea') mydiv.innerText = arr.join('\r\n') docum ...

Filter an object in Typescript and retrieve a single key

Managing a set of checkboxes is essential in assigning roles to new users. While it's possible to filter and retrieve only the checked checkboxes, extracting just the "name" key poses a challenge. The current method involves filtering with a for loop ...

When attempting to delete an item from Firebase using React, the re-render results in the item being

I'm currently in the process of developing an app to enhance my React skills, and I've chosen Firebase for data storage. Everything seems to be working fine as all items from Firebase are rendering properly. However, I've encountered an issu ...

Ways to check if an array is empty in Typescript

Every time I attempt to log in, the first thing I do is validate the search data stored in the database by querying information from a matrix. This code can be found in login.controller.ts export async function postLogin(req: Request, res: Response): Pro ...

The best practices for managing item spacing in React or React Native

I am facing some challenges while trying to adjust the spacing of my components. My goal is to have the grid occupy 90% of the screen, with the gear icon taking up the remaining 10% <View style={{ paddingLeft: insets.left, padding ...

Is it possible for Vue.js 2.x components to reference mixins?

jsfiddle It appears that referencing mixin methods (such as computed properties) from components is not allowed. In that case, how can I create a method that can be shared between both parent and child components? If mixins do not function in this manner, ...

Looking to dynamically track an event in Firestore?

Is it possible to implement a method in Node.js that allows me to listen for changes on a node, similar to the following path? organizations/{org_slug}/projects/{pro_slug}/calculations/{calc_slug} I have successfully done this in a Firebase Cloud Functio ...

Increase the detection range in empty lists for Vue-draggable-next

I am currently utilizing Vue-draggable-next in conjunction with Vue 3 to enable draggable lists within my application. In certain scenarios, users need to drag items from other lists into lists that are initially empty. I have noticed that the area for det ...

What is the timing for running tests using Yeoman AngularJS framework?

Recently, I created a compact Yeoman AngularJS project. Whenever I enter the command grunt serve, the application is launched and displayed in the browser. Surprisingly, whenever I make adjustments to a test, Grunt automatically reruns the test and provide ...

Changing Color of Specific Sticky Note in React - Customize Color of Individual Note Without Affecting Others

In React, I am working on a basic application for sticky notes that allows users to create as many of them as they'd like. One issue I'm facing is with changing the color of individual sticky notes – currently, when I change the color, it affe ...

How to retrieve an anchor element from a list using JavaScript

My current code loops through each <li> within a <td> cell and adds a class to the <li>. I have now inserted <a> tags between each <li> and am facing challenges in accessing the <a> tags. What I actually want is to assig ...

Exploring the functionality of utilizing dual loops with v-for in Vue.js

I am facing an issue with my table code where I need to repeat it 6 times to match the day column above. I would like to use v-for and make use of a variable called "count" which represents the number of days. Can someone assist me with this task? <tabl ...

Node.js (Express), passport.js, mongoose.js, and Android app all have in common the HTTP Error 307 - Temporary redirect

I am currently constructing a REST Api using Node.js (Express.js and Moongose.js). I have a single post route that takes JSON data and redirects it to the signup page (/app/signup) if the user is a first-time user (not found in the database), or to the log ...

Dynamically sending data to child components in Vue.js

I'm currently working on a progress bar implementation where the progress status is determined by the submitAction method. The value for the progress bar is constantly being updated in this method. Here's my code: 1. Parent Component <templa ...

Tips for incorporating a Forgot/Reset password option into your #Firebase platform

In the project I'm working on, I am utilizing #AngularFire2. My goal is to incorporate a Reset / Forgot password link into the login page. Does anyone have suggestions on how to accomplish this task? I'm looking to get some insights from #AskFi ...