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)
})
});
}
Related
This question already has answers here:
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 10 days ago.
I have a vue3 frontend set up with pinia as store, like this:
export const useShopStore = defineStore(
"shop",
() => {
const state = reactive({
data: {
fruits: [],
owners: [],
},
});
let data_copy = {
fruits: [],
owners: [],
};
async function fetchData() {
const URL = `${API_URL}/shops`;
await axios
.get(URL)
.then((res) => {
state.data = { ...res.data };
data_copy = { ...res.data };
})
.catch((err) => {
if (err.response) {
console.log(err.response);
}
});
}
return { data, data_copy, fetchData };
},
{
persist: true,
}
);
PROBLEM:
NO matter what i tried, the variable data_copy is always a reactive copy of data.state.
GOAL:
What i want to achieve is that i fetch the data and assign it
a.) to the reactive variable state.data as well as
b.) to the NON-reactive variable data_copy
REASON:
In the template, i have a checkbox group and a computed property to compare the arrays in state.data with the data object that was originally fetch, data_copy. If the state.data object changed, a button "Update changes" is enabled.
Meaning, after fetching the data from the API and assigning the result to data_copy, data_copy should never change.
I also tried Object.assign({}, res.data) instead of the deconstruction syntax, that also did not work.
QUESTION:
How can i get a truly constant copy from the fetchData result independent of state.data?
Thanks for you help!
Finally, i tried the following which works:
async function fetchData() {
const URL = `${API_URL}/shops`;
await axios
.get(URL)
.then((res) => {
state.data = JSON.parse(JSON.stringify(res.data));
data_copy = JSON.parse(JSON.stringify(res.data));
})
.catch((err) => {
if (err.response) {
console.log(err.response);
}
});
}
I found the answer here.
I am having some difficulties on executing local storage operations...
"react-native": "0.64",
"react-native-storage": "^1.0.1"
I'm using react-native-storage, as pointed in title, and I have created two simple methods for handling Writing and Reading:
import Storage from 'react-native-storage';
import AsyncStorage from '#react-native-community/async-storage';
const storage = new Storage({
size: 1000,
storageBackend: AsyncStorage,
defaultExpires: null,
enableCache: true,
sync: {
return: 'No data.'
}
});
const saveToLocalStorage = (key: any, data: any) => {
storage.save({
key,
data,
expires: null
})
}
const getFromLocalStorage = (key: any) => {
storage.load({
key,
autoSync: true
})
.then(data => {
return { data }
})
.catch(err => { });
}
export { saveToLocalStorage, getFromLocalStorage }
As you can see, it's pretty much the code example from https://www.npmjs.com/package/react-native-permissions.
At the App.tsx file, I do the following:
useEffect(() => {
saveToLocalStorage('test', 'test data');
const test = getFromLocalStorage('test');
}, [])
which returns undefined.
But if in the method getFromLocalStorage I replace
.then(data => {
return { data }
})
for
.then(data => console.warn(data));
the result is the image from bellow:
In short:
If the function returns the object from the storage, it brings undefined.
If the function returns a console.log from the storage, it brings what I've written on it.
because return { data } is not a valid expression for async functions
just use AsyncStorage, react-native-storage is not needed unless you develop for both mobile and web
useEffect(() => {
await AsyncStorage.setItem('test', 'myValue');
const value = await AsyncStorage.getItem('test');
console.log(value);
}, [])
I have to files with this code:
Users.vue
methods: {
obtenerUsuarios() {
console.log('Obtener Usuarios')
this.$store
.dispatch('auth/getValidToken')
.then((data) => {
console.log(data). // Console First Message
this.$store
.dispatch('user/fetchUsers', data)
.then((response) => {
this.items = response.data
})
.catch((error) => {
console.log(error)
})
})
.catch((error) => {
console.log('Error: ' + error)
})
},
},
Console Firsts Mesagge show me a json web token in console that is ok.
When i dispatch 'user/fetchUsers in
user.js
export const actions = {
fetchUsers({ jwt }) {
console.log('Action JWT:' + jwt) //Second console.log
return UserService.getUsers(jwt)
},
}
The second messaje show me: Action JWT:undefined in the console
if i change the line two to
fetchUsers(jwt) {
The second messaje show me: Action JwT:[object Object]
I need to pass a json web token from Users.vue method to fetchUsers action y user.js
I will to appreciate any help
Jose Rodriguez
Your action method currently declares the data in the first argument (and no second argument), but actions receive the Vuex context as its first argument. The data payload is in the second argument:
const actions = {
//fetchUsers(data) {} // DON'T DO THIS (1st arg is for context)
fetchUsers(context, data) {}
}
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)
})
}
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/')
})
})
},