I'm getting an error with my vue3 app. I'm trying to make a function in the methods{}
block which hits dynamodb, and creates a listmap of data, which I want to pass to a child component with props. I am calling the function that communicates with dynamoDB in the created(){}
block.
I'm not quite at the part of passing the data. Instead, I'm getting the following errors when trying to populate the productsData
object in the data(){}
block.
I'm setting the type of my products
prop
to be an interface I defined.
I am then casting that productsData
data
object to the products
prop
type.
For some reason, I am unable to push()
maps to the this.productsData
object as it is undefined
.
Here's the error
[Vue warn]: Missing required prop: "products"
at <Home onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <App> runtime-core.esm-bundler.js:6589
TypeError: _this.productsData is undefined
html:
<template>
<div class="home">
<HelloWorld :key="key" :products="products" />
</div>
</template>
typescript code:
<script lang="ts">
import { defineComponent, PropType } from "vue";
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";
import DBResponse from "@/interfaces/DBResponse";
import HelloWorld from "@/components/HelloWorld.vue";
export default defineComponent({
name: "Home",
components: {
HelloWorld,
},
props: {
products: {
type: Object as PropType<DBResponse[]>,
required: true,
},
},
data() {
return {
key: 0,
productsData: this.products,
};
},
methods: {
forceRerender() {
this.key = 1;
},
async getProductData() {
const region = process.env.VUE_APP_AWS_REGION as string;
const clientDynamoDB = new DynamoDBClient({
region,
credentials: fromCognitoIdentityPool({
identityPoolId: process.env.VUE_APP_IDENTITY_POOL_ID as string,
accountId: process.env.VUE_APP_AWS_ACCOUNT_ID,
clientConfig: { region },
}),
});
const query_input = {
TableName: process.env.VUE_APP_TABLE_NAME,
IndexName: "GSI1",
KeyConditionExpression: "SK = :sort_key and DK1 = :data_key",
ExpressionAttributeValues: {
":sort_key": { S: "PRODUCT#BLEND" },
":data_key": { S: "listed" },
},
Select: "ALL_ATTRIBUTES",
};
const command = new QueryCommand(query_input);
try {
const results = await clientDynamoDB.send(command);
const items = results.Items;
const cloudfrontHost = process.env.VUE_APP_CLOUDFRONT_HOST as string;
if (items) {
for (const key in items) {
const item = items[key];
this.productsData.push({
id: item.PK.S?.split("PRODUCT#")[1],
name: item.Name.S,
src: cloudfrontHost.concat(
"/products/assets/",
item.PK.S?.split("PRODUCT#")[1] as string,
".png"
),
description: item.Description.S,
price: item.Price.S,
});
}
}
} catch (err) {
console.error(err);
}
console.log(this.productsData);
this.forceRerender();
},
},
created() {
this.getProductData();
},
});
</script>
CodePudding user response:
productsData
is initialized to products
, but the products
prop is missing (as seen in the error message), so both are undefined
.
Based on your comment, you actually don't need the products
prop at all. You're setting up productsData[]
by pushing data into it in getProductsData()
(called from created()
hook), so the products
prop does not even come into play.
The solution seems to be to remove the products
prop, and initialize productsData
to an empty array with a type assertion (as DBResponse[]
):
export default defineComponent({
//props: {
// products: {
// type: Object as PropType<DBResponse[]>,
// required: true,
// },
//},
data() {
return {
//productsData: this.products,
productsData: [] as DBResponse[]
};
},
})