I am trying to transfer async data from a parent file to a child component. It is currently giving error in the child component as the parent loads the data in the onMounted event. What is the correct way to do this?
Parent:
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import TestForm from '../components/TestForm.vue';
const testMe = ref();
// testMe.value = {
// id: 1,
// startDateTime: '2023-06-26T09:43:32.203Z',
// };
onMounted(() => {
const newObject2 = fetchData();
console.log('onMounted testing newObject2', newObject2);
testMe.value = newObject2;
});
async function fetchData() {
const res = await fetch('http://localhost:4000/testMes');
const data = await res.json();
const newObject = data[0];
console.log('testing the async function data from json:', newObject);
return newObject;
}
</script>
<template>
<div>
<TestForm :testProps="testMe" />
</div>
</template>
Child: TestForm.vue
<script setup lang="ts">
import { ref } from 'vue';
const props = defineProps(['testProps']);
const startDateTime = ref('');
// eslint-disable-next-line vue/no-setup-props-destructure
startDateTime.value = props.testProps.startDateTime;
</script>
<template>
<div>
{{ startDateTime }}
</div>
</template>
I am getting the error:
TypeError: Cannot read properties of undefined (reading 'startDateTime')
which I think I understand why, but what is the right way to transfer these values to the child?
Since fetchData()
is an asynchronous function and we don't know when it will finish, you need to add the instruction to wait for the newObject2
variable to receive the result of the fetchData()
function. The instruction you should use is await
.
onMounted(async () => {
testMe.value = await fetchData(); // here
});
startDateTime.value = props.testProps.startDateTime;
This line is executed during component initialization and only assigns the value of testProps.startDateTime
to the startDateTime
reference once. This means that startDateTime
will not be automatically updated when testMe
changes in the parent component.
To make testProps
update with changes to the testMe
variable, the child component needs to watch testProps
and react to its changes. For this purpose, the onUpdated
lifecycle hook should be used in the child component.
const props = defineProps(['testProps']);
const startDateTime = ref('');
onUpdated(() => {
startDateTime.value = props.testProps.startDateTime;
});