Issue with Vuex map state being undefined when called from a component

Recently, I've been working on updating data in a component every time the Vuex state is not null. I have set up API routes with Laravel that return user information once they are logged in.

API routes:

Route::group(['middleware' => ['auth:api']], function () {
    Route::get('profil', 'Api\UserController@profil')->name('profile'); // will return user info
}

Vuex:

export default new Vuex.Store({
    state: {
        token: localStorage.getItem('token') || "",
        user: {}
    },
    getters: {
        isAuth: state => {
            return state.token != "" && state.token != null
        }
    },
    mutations: {
        SET_TOKEN(state, payload) {
            state.token = payload
        },
        SET_AUTH_USER(state, payload) {
            state.user = payload
        }
    }
})

In my App.vue file, in the created method, I commit SET_AUTH_USER with the HTTP response as the payload if the token exists.

App.vue:

<template>
  <div id="app-layout">
    <section-advices></section-advices>
</template>

<script>
    import SectionAdvices from "./SectionAdvices"

    export default {
        name: "app-layout",
        components: {
            SectionAdvices
        },
        created() {
            if (this.$store.state.token !== (null || "")) { 
                this.$http
                    .get("/profil")
                    .then(res => {
                        if (res.status === 200) {
                            this.$store.commit("SET_AUTH_USER", res.data.data);
                        } else {
                            this.$store.commit("SET_AUTH_USER", null); 
                        }
                     })
                     .catch(err => {
                         console.log(err);
                     });
            }
        }
    }
</script>

Everything seems to be working fine so far. Whenever I refresh the page and there's a token in my local storage, the user object always contains the user information.

SectionAdvices.vue:

<template>
    <section class="advices">
        <input type="text" v-model="name">
        <input type="text" v-model="email">
    </section>
</template>

<script>
    import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
        export default {
            name: "section-advices",
            data(){
                return{
                    name: null,
                    email: null
                }
            },
            computed:{
                ...mapState(["user"]),
                ...mapGetters(["isAuth"]),
            },
            created() {
                if(this.isAuth) { 
                    this.name = this.user.name 
                    this.form.email = this.user.email 
                 }
             }
        }
</script>

Despite having values for name and email in the user object according to Vue Dev tools, both are showing as "undefined" in the SectionAdvices component. Could it be that I'm calling the API in the wrong lifecycle inside App.vue?

Answer №1

Have you considered utilizing getters to retrieve state data? This can be beneficial in managing state during component lifecycles where the getters are initialized before page rendering.

Answer №2

The solution was discovered by me, here it is:

Following @dreijntjens' recommendation, I implemented a watcher in my "SectionAdvices.vue" file

...
watch: {
    // observing changes in store.state.user
    user: {
        handler: "fillForm", // invoking the method
        immediate: true // this watcher will run immediately after the component is created
    }
 },
 methods: {
    fillForm() {
        if(this.isAuth) { // not essential, just an added precaution. Once isAuth === true, the following code will execute
            this.form.name = this.user.name
            this.form.email = this.user.email
        }
    }
 }

The main issue arises when SectionAdvices.vue is being created and fetching data, while the store.state.user remains empty. As a result, my API calls are made after this step, rendering them ineffective. It's necessary to have a watcher to monitor any changes in the user state and update the local data within its respective component accordingly.

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

Attaching to directive parameters

I've been working on creating a draggable div with the ability to bind its location for further use. I'm aiming to have multiple draggable elements on the page. Currently, I've implemented a 'dragable' attribute directive that allo ...

The animation in ThreeJs encounters context issues within Angular 2

I am trying to incorporate ThreeJs into my Angular 2 project. I have successfully rendered a scene with a simple cube, but I ran into an issue when using the animate() function. Here is the code snippet: import { OnInit, Component } from '@angular/co ...

Simulated external prerequisite

//user.js const database = require('database'); exports.createUser = function(req, res){ let user = req.body; if( validateUser(user) ) { database.insertUser(user); //redirect } else { //render new page with the user data ...

Utilizing Vue.js to track and navigate through browsing history using the browser's

I'm currently working on an application using Vue and Laravel. Instead of relying on vue-router, Laravel is managing my routes. Within my parent component, I am dynamically loading components based on the state of an object in the data. One of the m ...

The speed at which a DIV moves when dragged with JavaScript mouse events is too fast

I am currently working on moving the #frame-slider-thumb across the image. Initially, I achieved this by monitoring the difference in mouseX position. However, a problem arose where if the thumb was not at 0 to start with, it would jump back to 0. To add ...

Building Your Initial HTTP Server using Node.js

Hey everyone, I'm relatively new to node.js but have made some progress. Following the steps in this tutorial, I was able to create my first "example" server. However, there are a few things that I don't quite understand. Could someone please exp ...

Display/Conceal JavaScript

I recently implemented a JavaScript function on my website to show/hide specific elements. However, being new to JavaScript, I have encountered some difficulties. I've spent quite some time troubleshooting the code but haven't been able to pinpoi ...

Creating an Engaging Discord Bot: A Step-by-Step Guide

I'm in the process of developing a Discord bot and I'm interested in adding a unique feature to it. I want to create an interactive system where users can request help through DM with the bot, and the support team can respond through the bot as w ...

Launching a pre-built React application

I'm facing an issue while attempting to run a pre-existing React App on my Mac locally. I have all the source files and node.js installed on my machine. Upon running npm install, I encountered a massive list of deprecations and npm ERRors that surpas ...

loading the css and javascript files based on the specified prop parameter

In the process of working on a ReactJS file that utilizes the react-ace library, I currently have the following code implemented. import React, { Component } from 'react'; import 'brace/mode/html'; import 'brace/theme/monokai&apos ...

What is the best way to navigate to a particular element on a webpage?

I am looking to implement functionality on my HTML page where users can 'scroll to' or 'focus on' a specific element. Traditionally, I would use an anchor tag with a href="#something". However, in this case, I am already utilizing the h ...

Utilizing HTTP POST method in vanilla JavaScript with AJAX

Having some trouble sending a post request to my PHP file as it keeps saying 'undefined index'. Here is my JavaScript code: document.getElementById("btn1").addEventListener('click', xh ); function xh(){ xhr = new XMLHttp ...

Ways to transfer data through the javascript success function in traditional CodeIgniter

Currently, I am working with an aging CodeIgniter application. I am trying to implement an onchange function that retrieves data from the controller and displays it in an input field that is part of an array. This is a snippet of the code on the view page ...

Trying to access the $dirty property of a component that does not contain a <form> tag

In my AngularJS 1.6 app, I have a component that dynamically generates checkboxes using ng-repeat. Here is an example: <div ng-repeat="subItem in item.ChildItemTypes"> <md-checkbox class="md-primary" ng-model="subItem.checked">{{ subItem.D ...

What is the best way to incorporate Tradingview's JavaScript into the render function of a React Typescript

I'm trying to incorporate some widgets into my Typescript React component. Here is the embed code export default class App extends React.Component { render(): ReactNode { return ( <div> Chart test <div className= ...

Check out the ViewUI Vue.js component that expands to reveal more content!

Is there a simple component to create the expand/collapse button with a blur effect like in all the demos? I see it used across different variations of the demos and am wondering if there is a specific component or demo showcasing how to achieve this effec ...

When employing TypeScript, an error pops up stating "cannot find name 'ObjectConstructor'" when attempting to use Object.assign

I am rephrasing my query as I realized it was unclear earlier. I have an API that is sending me data in the following format: {"photos":[{"id":1,"title":"photo_1_title"}]} In my code, I have a variable called photos and a function named getPhotos() For ...

Utilize styled-components in next.js to import and resize .svg files seamlessly

I have been attempting to import .svg files into my next.js project, but I have not had any success. I tried importing the .svg files the same way as in my React project by creating a typing.d.ts file and importing the svg as a component. However, it did ...

Guidelines for linking a promise function to a JSX component

How can we use React components to handle the result of a promise function and map it to JSX components? <Promise on={myFunc}> <Pending> ... </Pending> <Resolved> {(data: any) => ( ... )} ...

Adjusting the VueJS base URL for header configuration

Currently, I am in the process of building a system that relies on token-based authentication. After successfully capturing and storing the idToken within the store.js file, I proceeded to create a custom getter to access this value: returnToken(state) { ...