Answer the question
In order to leave comments, you need to log in
How to update data in 'newlevels' computed?
There is a component in which I get levels in a cycle. Each levlel has a favorite(levle.vaforite) property that is either true or false. Each level has a
`star` icon. The favorite function changes the value on the server from true to false. This works on the server, but does not update the x.favorite property in my `newlevels` computed.
import axios from 'axios'
const state = {
level: {},
levels: [],
question: {},
questions: [],
userlevels: []
}
const actions = {
// это я получаю когда логинюсь в моё app, к этому притензий нет
LEVELS: ({commit}) => {
axios.get('/ef/levels/')
.then(response => {
commit('LEVELS', response.data)
})
.catch(error => {
console.log(error, 'something went wront')
})
},
// это я диспатчу в компоненте
USERLEVELS: ({commit}) => {
axios.get('/ef/userlevel/')
.then(response => {
console.log('I am from USERLEVELS', response.data)
commit('USERLEVELS', response.data)
})
.catch(error => {
console.log(error, 'something went wrong')
})
},
// сдесь я отправляю на сервер true или false
// оно меняется на сервере, но не меняется в vue.js
USERLEVELS_PATCH: ({commit}, payload) => {
axios.patch('/ef/userlevel/' + payload.id + '/', payload.data)
.then(response => {
console.log('I am from USERLEVELS_PATCH', response.data)
})
}
}
const mutations = {
LEVELS: (state, data) => {
state.levels = data
},
USERLEVELS: (state, data) => {
state.userlevels = data
},
}
const getters = {
levels: state => state.levels,
userlevels: state => state.userlevels
}
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
computed: {
...mapGetters('ef', ["levels", "userlevels"]),
newlevels: function () {
this.levels.forEach(a => {
this.userlevels.forEach(b => {
if (a.id === b.level) {
a['favorite'] = b.favorite
a['complete'] = b.complete
a['progress'] = b.progress
a['userlevel_id'] = b.id
} else {
a['favorite'] = a.favorite || false
a['complete'] = b.complete
a['progress'] = b.progress || 0;
}
})
})
return this.levels
}
},
methods: {
favorite(level) {
let id = level.id
let data = {favorite: !level.favorite}
this.$store.dispatch('ef/USERLEVELS_PATCH', {id, data})
},
created() {
this.$store.dispatch("ef/USERLEVELS")
},
<v-flex v-for="x in newlevels'" :key="x.id">
<v-card>
<v-card-title>
<router-link :to="{ name: 'questions', params: {id: x.id} }">{{ x.level }}</router-link>
<v-spacer></v-spacer>
<v-icon :class="{star: x.favorite}" @click="favorite(x)">star</v-icon>
{{ x }}
</v-card-title>
</v-card>
</v-flex>
Answer the question
In order to leave comments, you need to log in
Let's sort it out in order:
1. When clicked, favorite(x) is called
2. favorite dispatches USERLEVELS_PATCH
3. USERLEVELS_PATCH sends a request to the server, logs the result, but does not commit anything
From point 3, we see that the store does not mutate - this is 1 problem
Further, what's the point in getters that just wrap the state?
const getters = {
levels: state => state.levels,
userlevels: state => state.userlevels
}
newlevels: function () {
return this.levels.map(level => {
return this.userlevels.reduce((acc, userlevel) => {
// если честно, меня еще дико смущает, что происходит тут... но автору виднее
if (level.id === userlevel.level) {
acc['favorite'] = userlevel.favorite
acc['complete'] = userlevel.complete
acc['progress'] = userlevel.progress
acc['userlevel_id'] = userlevel.id
} else {
acc['favorite'] = acc.favorite || false
acc['complete'] = userlevel.complete
acc['progress'] = userlevel.progress || 0;
}
return acc;
}, {...level});
});
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question