Inertia/Vue: keep getting props undefined error

29 Views Asked by At

I'm currently working on a project to learn Inertja + Vue + Tailwind to add to my Laravel stack. I'm currently stuck on processing the response from my calls to the backend via axios. I want to create a page with a graph where people can select filters to make the graph change. Selecting a filter from the dropdown/selection boxes triggers the correct functions, but I keep getting the "props is undefined" error in my browser console when I'm trying to use the response from the backend to overwrite the data for the graph and redraw it. I have tried passing the props variable to a number of functions; it is currently defined at the top of my code as well as at the bottom, but it keeps coming up as "undefined". Can anyone help me out?

<script setup>
import AppLayout from '@/Layouts/AppLayout.vue';
import { onMounted } from 'vue';
import Chart from 'chart.js/auto';

const props = defineProps({
    labelsArray: {
        type: Array
    },
    chartData: {
        type: Array
    },
    categories: {
        type: Array
    },
    tags: {
        type: Array
    },
    accounts: {
        type: Array
    },
    periods: {
        type: Array
    }
});
const createLineChart = (props) => {
    const lineChartElement = document.getElementById('lineChart');
    const lineChart = new Chart(lineChartElement, {
        type: 'line',
        data: {
            labels: props.labelsArray,
            datasets: props.chartData.data, // Ensure datasets is accessible in this scope
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
    return lineChart;
};

onMounted((props) => {
    const lineChart = createLineChart(props);
});

</script>

<template>
    <AppLayout title="Dashboard">
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Statistics
            </h2>
        </template>

        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">

                <div class="bg-white overflow-hidden shadow-xl sm:rounded-lg p-4 flex flex-wrap">
                    <div class="mx-2 flex flex-col">
                        <small>Accounts:</small>
                        <select id="account" multiple @change=updateAccounts class="bg-gray-50 border w-full border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500">
                            <option v-for="account in this.accounts" v-bind:value="account.id">
                                {{ account.name }}
                            </option>
                        </select>
                    </div>
                    <div class="mx-2 flex flex-col">
                        <small>Categories:</small>
                        <select id="categories" @change=updateCategories class="bg-gray-50 w-full border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500">
                            <option v-for="category in this.categories" v-bind:value="category.id">
                                {{ category.name }}
                            </option>
                        </select>
                    </div>
                    <div class="mx-2 flex flex-col">
                        <small>Tags:</small>
                        <select id="tag_id" @change=updateTags class="bg-gray-50 border w-full border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500">
                            <option v-for="tag in this.tags" v-bind:value="tag.id">
                                {{ tag.name }}
                            </option>
                        </select>
                    </div>
                    <div class="mx-2 flex flex-col">
                        <small>Starting period:</small>
                        <select id="tag_id" @change=updateStartDate class="bg-gray-50 border w-full border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500">
                            <option v-for="period in this.periods" v-bind:value="period.id">
                                {{ period.period }}
                            </option>
                        </select>
                    </div>
                    <div class="mx-2 flex flex-col">
                        <small>End period:</small>
                        <select id="tag_id" @change=updateEndDate class="bg-gray-50 border w-full border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500">
                            <option v-for="period in this.periods" v-bind:value="period.id">
                                {{ period.period }}
                            </option>
                        </select>
                    </div>
                </div>

                <div class="bg-white overflow-hidden p-4 mt-4 shadow-xl sm:rounded-lg">
                    <canvas id="lineChart" width="400" height="400"></canvas>
                </div>
            </div>
        </div>
    </AppLayout>
</template>

<script>
export default {
    name: "Filter.vue",
    methods: {
        fetch(props) {
            axios
                .post('http://financer.test/api/getTransactionsByFilter', {
                    tags: this.selectedTags,
                    categories: this.selectedCategories,
                    accounts: this.selectedAccounts,
                    starting_period: this.startdate,
                    end_period: this.enddate
                })
                .then(response => {
                    console.log(response);
                    props.chartData.data = response;
                })
        },
        updateAccounts(event) {
            this.selectedAccounts = [event.target.value];
            this.fetch()
            console.log(this.datasets.data)
        },
        updateCategories(event) {
            this.selectedCategories = [event.target.value];
            this.fetch()
            console.log(this.datasets.data)
        },
        updateStartDate(event) {
            this.startdate = event.target.value;
            this.fetch()
            console.log(this.datasets.data)
        },
        updateEndDate(event){
            this.enddate = event.target.value;
            this.fetch()
        },
        updateTags(event) {
            this.selectedTags = [event.target.value];
            this.fetch()
            console.log(this.datasets.data)
        }
    },
    data () {
        return {
            datasets: [],
            selectedAccounts: [],
            selectedTags: [],
            selectedCategories: [],
            startdate: '',
            enddate: ''
        }
    },
    props: {
        labels: Array,
        chartData: Array
    },
    mounted () {
        this.fetch()
    }
}
</script>
0

There are 0 best solutions below