Here is my RequestList.vue
component
<template>
<ion-item v-for="request in requests" @click="showRequest(request)" :key="request.id"
text-wrap>
<ion-label>
<b>Name:</b> {{ request.event.name }}
<br>
<b>Venue:</b>{{ request.event.venue.name }}
<br>
<b>Date:</b> {{ request.event.date }}
</ion-label>
</ion-item>
</template>
<script>
import {useRouter} from 'vue-router'
import {IonItem, IonLabel} from '@ionic/vue'
import store from '@/store';
export default {
components: {
IonLabel,
IonItem
},
props: {
requests: Array
},
setup(props) {
const router = useRouter()
const showRequest= (request)=> {
console.log('request', props.request);
store.requests.setRequest(props.requests);
};
return {router, showRequest}
}
}
</script>
My store/modules/requests.js
file
import {computed, ref} from "vue";
const state = ref({
request: null
});
export function setRequest(request) {
state.value.request = request;
}
export const getRequest = computed(() => state.value.request);
My Requests.vue
component where I am using the RequestList.vue
<template>
<ion-page>
<ion-header>
<ion-toolbar></ion-toolbar>
</ion-header>
<ion-content class="ion-padding-start ion-padding-end">
<ion-list-header>
<ion-label>
<b>Requests</b>
</ion-label>
</ion-list-header>
<div v-if="!loading">
<request-list :requests="requests" />
</div>
<div v-else>
<ion-spinner class="spin"></ion-spinner>
</div>
</ion-content>
</ion-page>
</template>
<script>
import { defineComponent } from 'vue'
import { IonContent, IonHeader, IonLabel, IonListHeader, IonPage, IonSpinner, IonToolbar } from '@ionic/vue'
import { reactive, toRefs } from '@vue/reactivity'
import { onMounted } from '@vue/runtime-core'
import RequestList from '../components/RequestList'
import firestoreService from '@/services/firestore'
export default defineComponent({
components: {
IonContent,
IonPage,
IonLabel,
IonHeader,
IonSpinner,
IonToolbar,
IonListHeader,
RequestList
},
setup() {
const state = reactive({
requests: [],
loading: false
})
onMounted(async () => {
state.loading = true
try {
state.requests = await firestoreService.getClaimableRequestsForCurrentUser()
} catch (e) {
console.log('error occurred fetching requests for current user', e)
} finally {
state.loading = false
}
})
return {
...toRefs(state),
}
}
})
</script>
My issue is that in RequestList.vue above, the showRequest
handler is sending request
as param which is a proxy. And thats why the store.requests.setRequest(props.requests)
is setting a proxy in the store. Whereas I need the value of props.requests.
So how do I do it here?
There are different ways to get the raw value of a proxy:
1. (My Recommended way) Vue 3 Reactivity utils functions, see Reactivity API:
import { isProxy, toRaw } from 'vue';
if(isProxy(proxyObject)){ //this If() block is not really necessary
const rawObject = toRaw(proxyObject)
}
//But it is not recommended to hold a persistent reference to the original object. Use with caution.
2. Using JSON stringify/parse:
const rawObject = JSON.parse(JSON.stringify(proxyObject));
3. Destructuring:
const rawObject = {...proxyObject};
4. Object.assign:
const rawObject = Object.assign({}, proxyObject);
The easiest way may be to use JSON stringify/parse
const showRequest = (request)=> {
const reqObject = JSON.parse(JSON.stringify(request));
console.log('request', reqObject);
store.requests.setRequest(reqObject);
};
Destructuring ({..request}
or Object.assign({}, request))
) sometimes works too, but only if you've got a single level of proxies, whereas the stringify/parse will work on the entire object (just make sure you don't have any cyclic object values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With