Passing table index to my vuex store - vuejs2

I am trying to pass the record to be deleted and the index of the table so it can be updated.
It seems the delete works fine but removing the right record from the table is not.
I ve tried a few variations and read a lot but still can't quite figure this out so seeking guidance please.
My component
//recordID - record to delete from API
// index - index in table
// console log returns correct info for both
onDelete (recordId, index) {
this.$store.dispatch('cases/deleteCase', recordId, index)
}
// also tried this.$store.dispatch('cases/deleteCase', (recordId, index)) but didn't work or delete
In my store I have
Action
deleteCase ({ commit, context }, data, index) {
console.log(data)
return new Promise ((resolve, reject) => {
//Delete works as expected
this.$axios.delete('/cases/' + data + '.json')
.then(
resolve(commit('DELETE_CASE', index))
)
.catch(e => {
context.error(e)
reject('/cases/')
})
})
},
My mutation
// delete a todo
DELETE_CASE (state, index) {
state.cases.splice(index, 1);
}
Many Thanks

Figured this out, sharing for others with similar issue
need to pass an object
onDelete (recordId, index) {
this.payload = {'recordId': recordId, 'index': index}
this.$store.dispatch('cases/deleteCase', this.payload)
}
Then I can separate out in my vuex action
deleteCase ({ commit, context }, payload) {
return new Promise ((resolve, reject) => {
this.$axios.delete('/cases/' + payload.recordId + '.json')
.then(
resolve(commit('DELETE_CASE', payload.index))
)
.catch(e => {
context.error(e)
reject('/cases/')
})
})
},

Related

how to get data with mapActions

I can't seem to get the data I need using mapActions from my store. I am doing an Axios GET (I turn that data to an array), and pass that data to my home.vue, and render a list of notes.
Now, it works fine if I use mapGetters, but to my understanding, I can access data directly from mapActions, I've seen people do it, but so far I can't. Or can I?
Home.vue:
export default {
methods:{
// Not Working
...mapActions(
['getNotes']
),
created(){
// Not working
this.getNotes()
console.log(this.getNotes())//returns pending Promise
}
}
my store.js
export default new Vuex.Store({
state: {
...other stuff in state...
// this is getting the notes from firebase
notes: {}
},
getters: {
...other getters...
notes: state => state.notes
},
mutations: {
...other mutations...
SET_NOTES (state, notes) {
state.notes = notes
}
},
actions: {
getNotes ({ commit }) {
axios.get('/data.json')
.then(res => {
const incoming = res.data
const notes = [] // <-- this is commited ok without explicit return
// converting object to array
// extracting firebase ids for manipulating existing notes
for (let key in incoming) {
const note = incoming[key]
note.id = key
notes.push(note)
}
console.log(notes)
commit('SET_NOTES', notes)
// return notes <-- tried that, no effect!
})
.catch((error) => {
console.log('Error: ', error)
})
},
...commiting 2 other things needed for my app
}
...other actions...
})
I don't see you have return the notes data as a return value inside your action getNotes(). At the end of your success callback all you did is commit your data into the notes commit('SET_NOTES', notes).
Return your notes data
getNotes ({ commit }) {
axios.get('/data.json')
.then(res => {
const incoming = res.data
const notes = []
// converting object to array
// extracting firebase ids for manipulating existing notes
for (let key in incoming) {
const note = incoming[key]
note.id = key
notes.push(note)
// array.reverse()
}
console.log(notes)
commit('SET_NOTES', notes)
// HERE YOU RETURN YOUR NOTES DATA
return notes
})
.catch((error) => {
console.log('Error: ', error)
})
}

Returning data from a Vuex action

Can I return data from a Vuex action or do I need to update the store?
I've got an action defined but it returns no data:
getData() {
return { "a" : 1, "b" : 2 }
}
You can actually return data from an action. From the documentation:
Actions are often asynchronous, so how do we know when an action is
done? And more importantly, how can we compose multiple actions
together to handle more complex async flows?
You should return a promise and the data in the resolve() method:
actions: {
actionA () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ name: 'John Doe' })
}, 1000)
})
}
}
And use it this way:
store.dispatch('actionA').then(payload => {
console.log(payload) /* => { name: 'John Doe' } */
})
Your code will work if the code that calls your action uses either 'await' or a callback.
For example:
const result = await store.dispatch('getData');
The main takeaway being that actions return promises even if the action isn't doing any asynchronous work!

get single record through axios in vuex store

I would like to return a single record from my back end using a Vuex store module in Nuxt.
I have the following in my component, which passes the value i want
( which is the $route.params.caseId )
created () {
this.$store.dispatch('cases/getCase', $route.params.caseId );
},
I pass the $route.params.caseId into my getCase action in my vuex store module as follows
getCase ({ commit, context }, data) {
return axios.get('http' + data + '.json')
.then(res => {
const convertcase = []
for (const key in res.data) {
convertcase.push({ ...res.data[key], id: key })
}
//console.log(res.data) returns my record from firebase (doesnt display the key though in the array, just the fields within the firebase record, but assume this is expected?
commit('GET_CASE', convertcase)
})
.catch(e => context.error(e));
},
the convert case is to extract the id from firebase key and add it to my array as id field (Is this correct for a single result from firebase in this way?)
My mutation
// Get Investigation
GET_CASE(state, caseId) {
state.caseId = caseId;
},
Now when I use Case Name: {{ caseId.case_name }} I'm not getting any result,
I'm not getting an error though, any thoughts on what i am doing wrong please
Many Thank
You can pass more data to an action like you did in the dispatch method and later access them normally.
Note the data parameter of the getCase function, in your example data === $route.params.caseId
//Load single investigation
getCase ({ commit, context }, data) {
return axios.get('http' + investigationID + '.json')
.then(res => {
const convertcase = []
for (const key in res.data) {
convertcase.push({ ...res.data[key], id: key })
}
commit('GET_CASE', convertcase)
})
.catch(e => context.error(e));
},
In case you want to use promises, check out the exemple below of a action in my app that fetches a single BLOG_POST
let FETCH_BLOG_POST = ({commit, state}, { slug }) => {
return new Promise((resolve, reject) => {
fetchBlogPost(slug, state.axios)
.then((post) => {
console.log("FETCH_BLOG_POSTS", post.data.data)
commit('SET_BLOG_POST', post.data.data)
resolve(post.data)
})
.catch((error) => {
console.log("FETCH_BLOG_POST.catch")
reject(error)
})
});
}

How can my vuex mutation dispatch a new action?

How can my vuex mutation dispatch a new action or how can my action get read access to the store?
Basically I've got a action that calls an mutation:
updateSelectedItems: (context, payload) => {
context.commit('updateSelectedItems', payload);
},
And the mutation that updates the list. It also gets any new items. I need to do something with these new items:
updateSelectedItems: (state, payload) => {
var newItems = _.differenceWith(payload, state.selectedItems, function (a, b) {
return a.name === b.name;
});
state.selectedItems = _.cloneDeep(payload);
_.each(newItems, (item) => {
// How do I do this??
context.dispatch('getItemDetail', item.name)
});
},
It's really not best practice to make your mutations do too much. It's best if they're super-simple and generally do one thing. Let your actions take care of any multi-step processes that might affect the state.
Your example would make more sense structured like this:
actions: {
updateSelectedItems(context, payload) {
var selectedItems = context.state.selectedItems;
var newItems = _.differenceWith(payload, selectedItems, (a, b) => {
return a.name === b.name;
});
context.commit('setSelectedItems', payload);
_.each(newItems, (item) => {
context.dispatch('getItemDetail', item.name)
});
},
getItemDetail(context, payload) {
// ...
}
},
mutations: {
setSelectedItems(state, payload) {
state.selectedItems = _.cloneDeep(payload);
}
}
If you really need to dispatch something from inside a mutation (which I'd highly recommend not doing), you can pass the dispatch function to the mutation as part of the payload.
It is technically possible using this to call dispatch or commit (or few others) ... i'm only mentioning this for anybody who comes here and needs it for their specific use case.
In my situation i'm using fiery-vuex library which actually passes a function as the payload that will return the updated data, i use this along with a refresh_time key in the db to determine when to refresh certain user data
SOME_MUTATION( state, getData() ){
const new_data = getData()
if( new_data.refresh_time > state.user.refresh_time ){
this.dispatch( 'refreshFromOtherStateMeta', state.user.id )
}
state.user = new_data
}

React Native Pass data to another screen

I need to pass some data from one screen to another, but I don't know how to do it. I've searched and I read about Redux, but it is a bit complicated since I never used it and most of the tutorials are confusing for a newcomer. But if I could do it without Redux, that would be better.
So, when I click in a button, It runs this:
onSearch() {
var listaCarros = fetch(`URL`, {
method: 'GET',
})
.then((response) => { return response.json() } )
.then((responseJson) => {
console.log(responseJson)
})
}
and I want to pass the data I get from this, to another screen.
Im using router-flux, if that matters.
you can save the response in state of your current component like
onSearch() {
var listaCarros = fetch(`URL`, {
method: 'GET',
})
.then((response) => { return response.json() } )
.then((responseJson) => {
console.log(responseJson);
/*for react-native-router-flux you can simply do
Actions.secondPage({data:responseJson}); and you will get data at SecondPage in props
*/
this.setState({
dataToPass :responseJson
});
})
}
then below in return like you want to pass data to a new component having named as SecondPage, you can do it in following way
render(){
return(
{this.state.dataToPass && <SecondPage data ={this.state.dataToPass}>} //you will get data as props in your second page
);
}