Values in Vuex do not get updated by getters

I'm having trouble understanding the functionality of getters in Vuex. The issue arises when I log out the token and find that the state and localStorage are empty, but the getters still contain the old token value. In the created lifecycle hook, I have the following code:

created: async function () {
    if (this.$store.getters.shortToken) {
      this.isConfirm = true
    }
    console.log(
      'signining', localStorage.getItem('token'), // ''
      'state', this.$store.state.user.token, // ''
      'getter', this.$store.getters.token // 'old-token'
    )
    if (this.$store.getters.token) {
      await this.$router.push({ path: '/' })
    }
  }

The getters section contains:

token: state => {
    return localStorage.getItem('token') || state.user.token
  }

And for the mutation:

SET_TOKEN: (state, payload) => {
      localStorage.setItem('token', payload.token)
      Object.assign(state, payload)
    }

However, the console log within created shows an empty localStorage token (expected behavior), empty state.token (also expected).. But, getters.token displays the token value (unexpected), despite setting SET_TOKEN with an empty token. Why is this happening?
PS. If I add a

console.log(state.user.token, localStorage.getItem('token'))
above the return statement in the getters token, the getters.token in the created hook becomes empty... WHY?
Here are some relevant codes for handling this scenario, starting with the logout method:

methods: {
    async logout () {
      if (await this.$store.dispatch('logOut')) {
        console.log('logged out')
        await this.$router.push({ path: '/signin' })
      }
    }
  }

Action for logging out

async logOut (context) {
    console.log('logggog')
    context.commit('SET_TOKEN', {
      token: ''
    })
    context.commit('SET_USER', {
      user: null
    })
    return true
  }

Answer №1

Getters play a crucial role in computing derived state based on the store state.

The issue arises when you return the value of localStorage.getItem() from your Getter, as it is not part of the store state and therefore not reactive or observable.

In Vuex, the Getter will only recalculate its value when there are changes to state.user.token, not when localStorage.setItem() is called.

To ensure that the Getter functions correctly, simply return the value of state.user.token. Additionally, consider adding a created hook in your App.vue to check for a token in localStorage and trigger the SET_TOKEN mutation if needed:

App.vue

<script>
    created() {
        const token = localStorage.getItem('token');
        if (token != null) {
            this.$store.mutations.SET_TOKEN({ token });
        }
    }
</script>

Remember to be cautious of change detection caveats when using Object.assign because Vuex mutations adhere to Vue's reactivity rules.

In your mutation function, consider either:

SET_TOKEN: (state, payload) => {
    localStorage.setItem('token', payload.token);
    state.token = payload.token;
}

or if payload represents state.user:

SET_TOKEN: (state, payload) => {
    localStorage.setItem('token', payload.token);
    state.user = {
       ...payload
    }
}

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

Tips for swapping a component with another component in React.js without the need for a page refresh

class Navigation extends Component { constructor(props) { super(props); this.state = { width: window.innerWidth, } } updateWidth = () => { if (this.state.width > 700) { this.setStat ...

Please ensure that the table is empty before reloading data into it

I am facing an issue while binding data from the database. The data is being bound every 5 seconds, however, it does not clear the previous data and keeps accumulating. Instead of displaying just 3 rows when there are 3 in the database, it adds 3 rows ev ...

There seems to be an issue with the DownloadDir functionality of the node-s3-client library, as

I am currently using a node s3 client library called 'node-s3-client' for syncing directories between S3 and my local server. As per the guidelines provided in the documentation, here is the code I have implemented: var s3 = require('s ...

Receive axios responses in the exact order as the requests for efficient search functionality

Currently, I am working on integrating a search feature in React Native using axios. For the search functionality, I am incorporating debounce from lodash to control the number of requests being sent. However, there is a concern about receiving responses ...

Can someone please advise me on how to output the value of a var_dump for an array using console.log?

After writing the code in this manner, it functions properly and returns a JSON object. public function getElementsAction() { $currency = App::$app->getProperty('currency'); if(!empty($_POST)) { $sql = 'SELECT name, p ...

Is `console.log()` considered a native function in JavaScript?

Currently, I am utilizing AngularJS for my project. The project only includes the angular.min.js file without any additional references to other JavaScript files. The code snippet responsible for sending requests to the server is as shown below: var app = ...

How can I completely alter the content of aaData in jquery.dataTables?

Looking to completely change the content of a datatable purely from a javascript perspective, without relying on Ajax calls. I've attempted using the following script: oTable.fnClearTable(); oTable.fnAddData(R); oTable.fnAdjustColumnSizin ...

Which codec strings are considered valid for the web codecs API?

I am searching for a definitive list of valid strings that can be passed as the `codec` parameter in `VideoEncoder.isConfigSupported({ codec, width, height })`, but I have been unable to find a clear answer so far: The TS declaration file states that it m ...

The slides on SlickJS are initially loaded in a vertical alignment, but once the arrows are interacted with,

I've put together a demonstration that highlights the issue I'm facing. Upon visiting the contact section, you'll notice that all the slickJS slides are stacked vertically initially, but once you interact with them by clicking on the arrow o ...

Obtain JSON data using jQuery

Hey there! I am currently working on understanding how to retrieve data using json/JQuery with the code below. After storing a php variable in a json variable (var ar), I confirmed its contents through console.log, although when I used document.write it d ...

JavaScript - Loading image from local file on Linux machine

I have a server running and serving an HTML page, but I am trying to display an image from a local drive on a Linux machine. I've tried using file://.., but it doesn't seem to be working for me on Ubuntu 18.04. There are no errors, the img tag ju ...

TimePicker Component for ASP.Net MVC with Razor Syntax

I'm currently working on implementing a TimePicker using Razor and JQueryUI in my bootstrap website. While I have successfully created a DatePicker, I am facing difficulties in creating a separate TimePicker using two different TextBoxes instead of se ...

Integrate Thymeleaf properties seamlessly into JavaScript code

I am attempting to embed a property from Spring's application.properties into JavaScript. It is working properly with the following code: <h1 th:utext="${@environment.getProperty('key')}"></h1> However, it returns null with th ...

It is impossible to perform both actions at the same time

Is it possible to create a progress bar using data attributes in JQuery? Unfortunately, performing both actions simultaneously seems to be an issue. <div class="progressbar"> <div class="progressvalue" data-percent="50"></div> </d ...

Is your iPhone struggling to display animation sprites correctly?

After testing on Android and iPhone, I found that the website works great on Android but lags on iPhone. I suspected that the issue might be related to image preloading, so I tried adding a simple jQuery preloader, but it didn't solve the problem. Th ...

Learn how to clear form values in react-bootstrap components

My objective upon clicking the register button is: Clear all input fields Hide any error tooltips Check out the CodeSandbox link I attempted to reset using event.target.reset();, but the tooltips persist on the screen. export default function App() { ...

Creating a dynamic image display feature using VueJS

Explore the connections between the elements How can I transmit a value from one child component to another in VueJS? The code snippet below is not generating any errors and the image is not being displayed <img v-bind:src="image_url" /> Code: & ...

Unable to transfer an array from getStaticProps method in Next.js

Whenever I pass a JSON array from getStaticProps in Next.js, I encounter this specific error message when trying to access it. TypeError: Cannot read property 'contentBody' of undefined module.exports../pages/[author]/[article].js.__webpack_expo ...

In a perplexing twist, requests made to the Express app arrive with empty bodies despite data being sent, but this anomaly occurs

Welcome to the community of inquisitive individuals on Stack! I'm facing an interesting challenge while developing an Express app. Despite everything running smoothly with two routes, I've hit a roadblock with one route that seems to have empty i ...

Run code once the Firestore get method has completed its execution

Is it possible to execute code after the get method is finished in JavaScript, similar to how it can be done in Java (Android)? Below is an example of my code: mColRef.get().then(function(querySnapshot){ querySnapshot.forEach(function(doc) { ...