Attempt to accessing Vuex state after its cleanup - vue.js

I have a problem with cleaning up Vuex state at logout and continuing attempts to access to the state from the component.
A component uses object from state:
<custom-card
color="green"
:name="this.author.name"
:surname="this.author.surname"
>
An "author" object is obtained using getters, from "computed":
computed: {
...mapGetters({
author: 'author'
}),
},
When I'm trying to logout being on the page with the card component, I am redirected to the login page (as intended) and at the same time I got an error in console:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of null"
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'name' of null
It's clear for me, that 'author' is set to null at logout and this is why the error occur. But it isn't clear for, why this is happening. I thought after click on logout button, vue-router should redirect me to the login page and content of the previous page doesn't matter after that.
How can I avoid these errors?
Upd. I think an anwer on this question can be found in "Rectivity in Depth" article on Vuejs documentation:
Since Vue doesn’t allow dynamically adding root-level reactive properties, you have to initialize Vue instances by declaring all root-level reactive data properties upfront, even with an empty value.
If you don’t declare message in the data option, Vue will warn you that the render function is trying to access a property that doesn’t exist.

Related

Ref's validation's result is different in mounted lifecycle hook

I have a componentized form where I have a different ref for each component and I need to validate these refs once the component is created. The problem is that during the created the refs are undefined and in the mounted the validation is giving an incorrect result for some refs.
testing exactly the same validation after mounting, gives the expected result

Vuex & Storybook: Cannot set reactive property on undefined, null, or primitive value: undefined

I'm having an issue when using Vuex with Storybook. I have made a little basic app using the Vue CLI and Storybook v5.3 to demonstrate the problem. The code can be found at this repo on github.
Essentially, I'm trying to commit input field data to my store. However, I get a Vuex warn: "Cannot set reactive property on undefined, null, or primitive value: undefined" and a TypeError: "index.js:47 TypeError: Cannot use 'in' operator to search for 'foo' in undefined".
I have no idea why it doesn't work because I'm not really doing anything complex. The only thing I can think of is that Vue and Vuex just don't play well with React which is what Storybook is developed with.
Has anyone come across this before?
Cheers.
I found some issues in the component and store on GitHub. After correcting them I was able to run it without errors.
Firstly, there is no data-index attribute on the <input>. Once this is added, it must be parsed to an integer so it can be used as an array index in the store mutation.
Secondly, the use of Vue.set() is incorrect. The expected arguments are:
An existing reactive object/array.
A property/index that you want to add and be reactive.
The value of the new property/index.
Try changing
Vue.set(state.myData[index], "foo", data);
to
Vue.set(state.myData, index, {"foo": data});
https://v2.vuejs.org/v2/api/#Vue-set
Shouldn't you be using dispatch instead of Vue.set in Vuex? (storeModule.js)

Why does my computed property's state show as blank in mounted hook, but fine everywhere else?

As the topic suggests, I have a particular item in my vuex store which I am bringing into my component in the computed properties section using mapState. This is the code for it:
computed: mapState({
orderTitle: state => state.order.bookTitle,
}),
When I inspect this in the Vuex section of Vue Dev Tools, I can see that it is accurately getting the data from the store.
Now the problem.
I have an input text field which I have put a v-model on, and associated it with a data property. What I want to do is pre-populate that text field with the text found in orderTitle which I am getting from my store.
I tried doing this by simply assigning the value in the computed property to the data property in the mounted hook. However, this didn't work.
When I tried to troubleshoot it by doing console.log(this.orderTitle) to see the value of the computed property in the mounted hook, it showed up as blank.
How come the value is properly appearing in the Vue Dev Tools (and even in the console when I do $vm0.orderTitle) but not in the mounted hook?
Any thoughts?
Thanks!
Sounds like a "this scope" problem.
Try with
computed: mapState({
orderTitle (state) {
return state.order.bookTitle
}
}),
I figured it out. Instead of performing the actions in the mounted hook, I did it in the updated hook, which fires much later in the Vue instance lifecycle (after the Virtual DOM is re-rendered & patched).

Problems with dynamically resetting object references in vuejs + vuex

I am coding a web app with vuex and firestore. In my main.js, under created(), I am calling a vuex action (defined in a store module) to query the firestore db and bind a certain subset of the objects in the collection to vuex, restricted programmatically. Summing up:
Let me simplify my question. Here is my structure:
<template> has a v-for list feeded by the computed() property below.
mounted () a function calling vuexfire action binding db RESTRICTED collection to state.ref
computed () some c. property returning a list of state.ref
methods () some method callong vuexfire action binding db UN***RESTRICTED collection relative to some WHERE TO parameter to state.ref
I want to be able to call the method sometimes to reset state.ref to the UNRESTRICTED set of db objects.
My problem is that calling the method triggers no error, but seems to fail: the computed() list returns no object.

I have a TypeError warning but the app works fine

Suddenly I started getting the following TypeError warning from Vue but my app works fine
[Vue warn]: Error in render: "TypeError: Cannot read property 'Name' of null"
This is coming from a data property named 'dashboard' that is loaded via AJAX call after user selects an item from a drop down. In debugging I have been able to simplify the code to get the warning and learned how to not get the warning.
This line will give me the warning but works fine
Dashboard: {{dashboard.Name}}
This line will display the entire dashboard object with no warning
Dashboard: {{ dashboard}}
This line works fine as well with no warning
Dashboard: {{ dashboard == null ? "Null" :dashboard.Name}}
I'm doing my first project with Vue and have had this code in working just fine for a couple of weeks, with no warnings.
Why all of a sudden do I start seeing this warning?
Secondary question is how do you typically track down such warnings. The stack trace is all in Vue code and gives me no idea where the problem originates from in my code.
The Vue team explained this in an answer from their forums here. I'll repeat a shorter version below as it took awhile to get it into my thick head.
A TypeError will be emitted when Vue does its rendering and the state of the data is not yet complete, in my case data was not yet set by the async AJAX call. When the AJAX call does return the data reactivity kicks in and the render is done again and this time the data is in a valid state.
This explains why the below has a TypeError but renders just fine
Dashboard: {{dashboard.Name}}
The TypeError is because Vue is attempting to render null.Name on initial rendering, i.e. dashboard is initially set to null. After the AJAX call returns, dashboard is now set and Vue reactivity kicks in and second rendering works as expected.
This below does not emit the TypeError warning because accessing\rendering null
Dashboard: {{ dashboard}}
is valid with nothing to render so no TypeError, after the AJAX call returns reactivity causes a re-render which displays the data as expected.
Resolution, quoted from the mentioned post.
Generally speaking you would put a conditional render either around your component, or the data that may require that information with a v-if statement to trigger a truthy expression. As null is “false”. When ajax fills it in it becomes “truthy”