I have made a vuex module to keep the user state of the data. It looks like this:
import Vue from "vue";
export default {
namespaced: true,
state: {
data: {},
meta: {}
},
mutations: {
setInitialUserData: function(user){
state.data = user;
},
setUserMeta: function(meta){
state.meta = meta;
},
},
actions: {
setInitialData: function({commit}, user){
console.log(user);
commit('setInitialUserData', user.user);
commit('setUserMeta', user.userMeta);
},
},
getters: {
getUser: (state) => state.data,
getUserMeta: (state) => state.meta
}
}
I am trying to save the data on login in my component like this:
this.$backend.post('/user/login', null, payload)
.then(response => {
this.$store.dispatch('auth/login', response.data.token);
this.$store.dispatch('user/setInitialData', response.data.user);
//this.$router.push('intranet');
})
.catch(error => {
//console.log(error);
});
}
The data that I get here:
setInitialData: function({commit}, user){
console.log(user);
commit('setInitialUserData', user.user);
commit('setUserMeta', user.userMeta);
},
},
Looks like this:
"user": {
"name": "John Doe",
"nice_name": "John",
"login_name": "John",
"email": "john#gmail.com"
},
"userMeta": {
"department": "Administrasjon",
"region": "Oslo",
"industry": "Bane"
},
But, nothing gets saved to state, on inspecting the vuex state, I get empty objects for both user data and user meta:
user:Object
data:Object (empty)
meta:Object (empty)
You are not passing the state to your mutators:
mutations: {
setInitialUserData: function(state, user){
state.data = user;
},
setUserMeta: function(state, meta){
state.meta = meta;
},
},
Related
I am currently working on a nuxtJS app in which the session seems to be lost after any refresh (although only in dev, not while deployed). I've tried to look up in the auth module of nuxt, and have tried many answers on google, but nothing seems to work and I'm a bit lost.
nuxt.config.js
auth: {
strategies: {
local: {
scheme: 'refresh',
token: {
property: 'token',
maxAge: 3600,
global: true,
},
refreshToken: {
property: 'refresh_token',
data: 'refresh_token',
maxAge: 60 * 60 * 24 * 30,
},
user: {
property: 'user',
},
endpoints: {
login: { url: '/authentication_token', method: 'post' },
refresh: { url: '/refresh/token', method: 'post' },
logout: false,
user: { url: '/api/user', method: 'get' },
},
autoLogout: true,
},
},
},
LoginMenu.js
methods: {
async onSubmit() {
try {
const response = await this.$auth.loginWith('local', {
data: this.login,
});
if (response.status === 200) {
await this.$auth.setUser({
email: this.login.email,
password: this.login.password,
});
await this.$router.push('/');
}
else {
this.loginFail();
}
}
catch (e) {
this.loginFail();
}
},
loginFail() {
this.showError = true;
},
},
nuxt auth.js
import Middleware from './middleware'
import { Auth, authMiddleware, ExpiredAuthSessionError } from '~auth/runtime'
// Active schemes
import { RefreshScheme } from '~auth/runtime'
Middleware.auth = authMiddleware
export default function (ctx, inject) {
// Options
const options = {
"resetOnError": false,
"ignoreExceptions": false,
"scopeKey": "scope",
"rewriteRedirects": true,
"fullPathRedirect": false,
"watchLoggedIn": true,
"redirect": {
"login": "/login",
"logout": "/",
"home": "/",
"callback": "/login"
},
"vuex": {
"namespace": "auth"
},
"cookie": {
"prefix": "auth.",
"options": {
"path": "/"
}
},
"localStorage": {
"prefix": "auth."
},
"defaultStrategy": "local"
}
// Create a new Auth instance
const $auth = new Auth(ctx, options)
// Register strategies
// local
$auth.registerStrategy('local', new RefreshScheme($auth, {
"token": {
"property": "token",
"maxAge": 3600,
"global": true
},
"refreshToken": {
"property": "refresh_token",
"data": "refresh_token",
"maxAge": 2592000
},
"user": {
"property": "user"
},
"endpoints": {
"login": {
"url": "/authentication_token",
"method": "post"
},
"refresh": {
"url": "/refresh/token",
"method": "post"
},
"logout": false,
"user": {
"url": "/api/user",
"method": "get"
}
},
"autoLogout": true,
"name": "local"
}))
// Inject it to nuxt context as $auth
inject('auth', $auth)
ctx.$auth = $auth
// Initialize auth
return $auth.init().catch(error => {
if (process.client) {
// Don't console log expired auth session errors. This error is common, and expected to happen.
// The error happens whenever the user does an ssr request (reload/initial navigation) with an expired refresh
// token. We don't want to log this as an error.
if (error instanceof ExpiredAuthSessionError) {
return
}
console.error('[ERROR] [AUTH]', error)
}
})
}
I am rendering a jspreadsheet component with data fetched from fastapi.
<template>
<h1>Synthèse évaluation fournisseur</h1>
<VueJSpreadsheet v-model="data.table" :options="myOption" />
{{ data.columns }}
</template>
<script>
import { reactive, onMounted, isProxy, toRaw, ref } from "vue";
import VueJSpreadsheet from "vue3_jspreadsheet";
import "vue3_jspreadsheet/dist/vue3_jspreadsheet.css";
export default {
components: {
VueJSpreadsheet,
},
setup() {
// var intervalID = setInterval(init, 3000);
var data = reactive({
table: [],
columns: [],
});
async function load_data() {
const response = await fetch("http://LOCALHOST:8080/supplier_overview");
return await response.json();
}
load_data().then((response)=>{
data.table=JSON.parse(response.result.data)
data.columns=(response.result.columns)
});
console.log(data.columns)
const myOption = ref({
columns: data.columns,
search: true,
filters: true,
includeHeadersOnDownload: true,
includeHeadersOnCopy: true,
defaultColAlign: "left",
tableOverflow: true,
tableHeight: "800px",
parseFormulas: true,
copyCompatibility: true,
});
return {
data,
myOption,
};
},
};
</script>
whereas data.columns is rendered correctly in the template, I cannot pass it to myOptions .
The proxy is empty with console.log(data.columns) whereas {{data.columns}} returns the correct array :
[ { "title": "period" }, { "title": "fournisseur" }, { "title": "Qualité" }, { "title": "Rques Qualité" }, { "title": "Logistique" }, { "title": "Rques Logistique" }, { "title": "Cout" }, { "title": "Rques Cout" }, { "title": "Système" }, { "title": "Rques Système" }, { "title": "Mot QLCS" }, { "title": "Note" }, { "title": "Rques" } ]
Any ideas why I cannot passed it correctly to myOptions ?
This problem has nothing to do with the variable myOptions
setup() {
async function load_data() {
const response = await fetch("http://LOCALHOST:8080/supplier_overview");
return await response.json();
}
//the function is async, 1 will be called after 2, so the result is empty
load_data().then((response)=>{
data.table=JSON.parse(response.result.data)
//1
data.columns=(response.result.columns)
});
//2
console.log(data.columns)
}
I am collecting data using get and set for my form. I want to post the states to the api.
How can I move the states or group them somehow so I can pass them as to action?
state: {
firstname: "",
lastname: "",
},
mutations: {
setFirstName(state, value) {
state.firstname = value
},
setLastName(state, value) {
state.lastname = value
},
So it looks like this:
sendInfo({commit}, object) {
axios.post('API_URL', object)
.then((response) => {
...
})
}
computed: {
firstname: {
get() {
return this.$store.state.firstname
},
set(value) {
this.$store.commit("setFirstName", value)
}
},
or am I approaching this wrongly?
It's probably best to put these values inside a state object like:
state: {
user: {
firstname: '',
lastname: ''
}
}
You can set the object in an action
actions: {
setData({ commit }, payload) {
commit('SET_DATA', payload);
}
},
mutations: {
SET_DATA(state, payload) {
state.user = payload;
}
}
It also makes it concise when using mapState:
computed: {
...mapState(['user'])
}
I have medications object as follow:
medications: [
{
'name': 'abc',
'id': naks23kn,
'resident': //this is resident id, resident is another object
.........
},
{.......},.....
]
I wanted to add another field residentName on this object list or is there any way so that I can display 'residentName' in the v-data-table ?:
medications: [
{
'name': 'abc',
'id': naks23kn,
'resident': //this is resident id, resident is another object
'residentName': 'ad' //set this new field
.........
},
{.......},.....
]
I am using `v-data-table> as :
<v-data-table
:headers="headers"
:items="medications"
:items-per-page="20"
:search="search"
class="elevation-23"
>
Now I want to add an residentName field based on the resident field. For this I did the following:
export default {
data() {
return {
medications: [],
}
},
computed: {
...mapGetters([
'allMedications', //this is used to get all medication from medication store
'getResidentsById',
]),
},
created() {
this.get_resident_list(),
this.get_registered_medication_list();
},
methods: {
...mapActions([
'get_registered_medication_list', //this is used to call API and set state for medication
'get_resident_list', //this is used to callAPI and set state for resident
]),
getResidentName(id) {
const resident = this.getResidentsById(id)
return resident && resident.fullName
},
},
watch: {
allMedications: {
handler: function () {
const medicationArray = this.allMedications;
console.log("Created this");
this.medications = medicationArray.map(medication => ({
...medication,
residentName: this.getResidentName(medication.resident)
})
);
},
immediate: true
},
}
}
In header
headers: [
{ text: 'Medication Name', value: 'name' },
{ text: 'Resident', value: 'residentName' },
]
This is in resident.js getter module
getResidentsById: (state) => (id) => {
return state.residents.find(resident => resident.id === id)
}
Edit: This is working, i.e I am getting residentName when the page is created but if I refresh the page then I get residentName=undefined
You can use map to add new prop to your each item in array
let medications = [{
name: 'abc',
id: 'naks23kn',
resident: 1
}]
medications.map(item => item.residentName = "Your Resident Name")
console.log(medications)
This should work
watch: {
allMedications: {
handler: function() {
const medicationArray = this.allMedications;
console.log("Created this");
this.medications = medicationArray.map(medication => medication.residentName = this.getResidentName(medication.resident)));
},
immediate: true
},
}
i am working a typeahead. and my typeahead accept a array list like ['Canada', 'USA', 'Mexico'].
and now i have a axios api to get a list of country. but i don't know how can i convert to a array list. Now work if hardcode a country list.
<vue-bootstrap-typeahead
:data="addresses"
v-model="addressSearch"
/>
data() {
return {
addresses: ['Canada', 'USA', 'Mexico'],
addressSearch: '',
}
},
axios.get('api_link', {})
.then(function (response) {
//How can i create a array list from api return useing name like addresses?
})
And my api return:
[
{
"id": 1,
"name": "Canada"
},
{
"id": 2,
"name": "USA"
},
]
Make use of the created() lifecycle hook to get the data:
created() {
axios.get('api_link', {})
.then((response) => { this.addresses = response.data.map(x => x.name) })
}
In your data() make sure to initialize to an empty array:
data() {
return {
addresses: [],
...
}
Just so you see what the map function does:
console.log([ { "id": 1, "name": "Canada" }, { "id": 2, "name": "USA" }, ].map(x=>x.name))
You can use array.map to take only the names like this:
axios.get('api_link', {})
.then((response) => {
this.addresses = response.data.map(country => country.name)
})