Navigating around potential type errors when passing data for chart.js can be challenging. Here are some strategies to

I'm currently working on an application that includes a chart, and I'm facing an issue while trying to populate the chart with data from my store. The error occurs when I attempt to pass the chartData object through props to the data property of the line Chart (3rd line in the chart component).

Property 'datasets' is missing in type 'Record<string, any>' but required in type 'ChartData<"line", (number | Point | null)[], unknown>'.ts(2741)

index.d.ts(3790, 3): 'datasets' is declared here.

types.d.ts(12, 5): The expected type comes from property 'data' which is declared here on type '{ readonly data: ChartData<"line", (number | Point | null)[], unknown>;'.

The chart component is being rendered in the User.vue file.

    <template>
        <div class="profile-container">
    
            <div class="user-container card">
                <img class="round-image" src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png">
                <div class="username">{{user?.name}}</div>
            </div>
            <div class="card statistics-container">
                <div class="rank"><span><font-awesome-icon class="icon" icon="fa-solid fa-crown" /></span> 2nd place</div>
                <div class="statistics">
                    <div><span>MAX WPM:</span> {{ user?.analytics.max_wpm }}</div>
                    <div><span>AVG WPM:</span> {{ user?.analytics.average_wpm }}</div>
                    <div><span>AVG ACC:</span> {{ user?.analytics.average_accuracy }}%</div>
                    <div><span>TOTAL TESTS:</span> {{ user?.analytics.number_of_tests }}</div>
                </div>
            </div>
            
            <chart class="chart" :chartData="chartData" :chartOptions="chartOptions"></chart>
            
    
        </div>
    </template>
    
    <script setup lang="ts">
        import { ref } from 'vue';
        import Chart from '../components/Profile/Chart.vue'
        import { useUserStore } from '~/store/User/UserStore';
        import {  ChartType } from 'chart.js';
    
        const { $axios } = useNuxtApp();
    
        const userStore = useUserStore();
    
        const showPassword = ref(false);
    
        const chartData = computed(() =>{
            const currentUser = user.value; // Use .value shorthand
            const typingTestResults = currentUser?.typingTestResults;
    
            return {
                type: 'line' as ChartType,
                labels: typingTestResults?.map(result => result.created_at),
                datasets: [
                    {
                        label: 'WPM',
                        data: typingTestResults?.map(result => result.wpm),
                        acc: typingTestResults?.map(result => result.accuracy),
                        time: typingTestResults?.map(result => result.duration_seconds),
                        backgroundColor: 'rgba(255, 174, 0, 0.2)',
                        borderColor: color: 'rgb(255, 174, 0)',
                        borderWidth: 3,
                        pointRadius: 6,
                        tension: 0.1,
                    }
                ],
            };
        });
    
            
        const chartOptions = {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                x: {
                    title: {
                        display: true,
                        text: 'Dates',
                        font: {
                            size: 16,
                            family: 'RobotoMono'
                        }
                    }
                },
                y: {
                    title: {
                        display: true,
                        text: 'WPM',
                        font: {
                            size: 16,
                            family: 'RobotoMono'
                        }
                    }
                }
            },
            plugins: {
                tooltip: {
                    mode: 'index',
                    intersect: false,
                    callbacks: {
                        label: (context) => {
                            const wpm = `- WPM: ${context.parsed.y}`;
                            const acc = `- ACC: ${context.dataset.acc[context.dataIndex]}%`;
                            const time = `- Time: ${context.dataset.time[context.dataIndex]}s`;
                            return [wpm, acc, time];
                        }
                    },
                    displayColors: false,
                    bodyFont: {
                        size: 17,
                        family: 'RobotoMono'
                    }
                    
                },
                legend: {
                    display: false 
                }
            }
        }
    
        const togglePasswordVisibility = () => {
            showPassword.value = !showPassword.value;
        };
    
        const user = computed(()=>{
            return userStore.user;
        })
    
        onMounted(async () =>{
            if(!userStore.user){
                userStore.user = (await $axios.get('/user')).data.data;
            }
            console.log(user);
        })
    </script>

Here's how my Chart component has been defined:

<template>
    <div>
      <Line :data="chartData" :options="chartOptions"></Line>
    </div>
</template>

<script setup lang="ts">
    import { Line } from 'vue-chartjs'
    import {
        Chart as ChartJS,
        CategoryScale,
        LinearScale,
        PointElement,
        LineElement,
        Title,
        Tooltip,
        Legend
    } from 'chart.js'

    ChartJS.register(
        CategoryScale,
        LinearScale,
        PointElement,
        LineElement,
        Title,
        Tooltip,
        Legend
    )

    const props = defineProps({
        chartData: {
            type: Object,
            required: true
        },
        chartOptions: {
            type: Object,
            required: true
        }
    });

And this is how my store looks like:

import { TypingTestResult, User } from './../../types/User';
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    user: {
      id: 0,
      name: '',
      email: '',
      typingTestResults: [] as TypingTestResult[],
      analytics: {
        max_wpm: 0,
        average_wpm: 0,
        average_accuracy: 0,
        number_of_tests: 0,
      },
    } as User,
  }),
});

Answer №1

Your chart data definition needs to be adjusted due to a bug in the current setup. Here is a revised version that should resolve the issue:

const updatedChartData = computed(() => {
    const currentUser = user.value;
    const typingTestResults = currentUser?.typingTestResults;

    return {
        labels: typingTestResults?.map(result => result.created_at),
        datasets: [
            {
                label: 'WPM',
                data: typingTestResults?.map(result => result.wpm),
                backgroundColor: 'rgba(255, 174, 0, 0.2)',
                borderColor: 'rgb(255, 174, 0)',
                borderWidth: 3,
                pointRadius: 6,
                tension: 0.1
            }
        ],
    };
});

This adjusted code eliminates the additional properties like acc and time within the chart data, fixing the issue you were experiencing.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for converting asynchronous function calls into synchronous functions in Node.js or JavaScript?

Imagine you are managing a library that provides access to a function called getData. Users utilize this function to retrieve real data: var output = getData(); In the background, the data is stored in a file, so you have implemented the getData functi ...

transferring information from Facebook to a web address through ZAPIER

Looking for guidance on sending data from Zapier to FB lead fetch. Is there a direct way to do this or is an external PHP file necessary? I need to extract name and email and send it to my CRM that is not supported by Zapier, but can receive data through U ...

Caution: The current version of the package has been deprecated and is no longer supported. It is advisable to update to the newest version available

While executing the npm install -g node-inspector command, I encountered an error message that prompts me to upgrade something. Unfortunately, I am unsure of what needs upgrading and how to do it. The complete error message I received is as follows: C:&b ...

How to implement a service function to handle $http responses in a controller

Is it possible to use $http only for my service and not the controller? I am getting undefined in my console.log when trying to display data in a $scope. Here is my code: app.controller('adminControl', ['$scope','$routeParams&apo ...

Argument for setInterval function

As a newcomer to programming, I am attempting to develop a basic javascript game. I have encountered an issue with the window.setInterval function and it seems to be causing everything to malfunction. I have been following a tutorial at this link and att ...

The NodeJS req.query is providing inaccurate information

When I send a JSON from the Client-Side to a NodeJS Server, it looks like this: $.ajax({ type: "POST", dataType: "jsonp", url: "www.xyz.com/save", data: { designation: "Software Developer", skills: [ "", "ASP.NET", "P ...

Unable to verify the el-select elementUI

I have attempted to implement custom validation with el-select in the following manner: Within my template: <el-form ref="form" > <el-form-item prop="fieldProp"> <el-select class="dialog-select" v-model="informationForm.age" @change=" ...

Broadcast to every socket except the one that is malfunctioning on Socket.io

My current task involves sending a message to all connected sockets on my server using socket.io. The code I have written so far looks like this: if(electionExists) { var connectedClients = io.sockets.adapter.rooms[electionRequested].sockets; ...

What could be causing Next.js to throw an error upon completion of the MSAL OAuth process?

I encountered an error while building a website using next.js. The site is set up for production, and after the authentication process with MSAL for Azure AD integration, I am facing the below error during the OAuth loop. As a beginner in next.js coming fr ...

The useParams() function will return an empty value upon the component's initial render

I'm utilizing React along with the following libraries: "babel-eslint": "10.0.3", "react": "^17.0.2", "react-dom": "^17.0.2", "react-redux": "^7.2.4", "react-router-dom": "^6.3.0", "react-scripts": "3.2.0", "redux": "^4.1.1 ...

I'm uncertain about how to preview the Nuxt3 application that I've generated

After creating a Nuxt3 in static mode, I want to preview it without having to push it to Netlify every time. My nuxt.config.js remains unchanged: import { defineNuxtConfig } from 'nuxt' export default defineNuxtConfig({ }) However, when trying ...

Leveraging Javascript/jquery to retrieve image data for a specific frame within a video

Query My aim is to optimize the code for image manipulation on a web browser using JavaScript. One possible solution I am considering is utilizing a video file to reduce HTTP requests. Is there a way to extract a single frame from a video in png, jpg, or ...

Ways to access information from doc.data()

<template> <div> {{ id }} {{ title }} </div> </template> <script> import { useRoute } from 'vue-router' import 'firebase/firebase-firestore' import { db } from '@/fdb' export default ...

Issue encountered while attempting to set up react-native project

Whenever I attempt to create a new react-native project using the command: npx react-native init myproject I encounter the following errors: ERESOLVE is overriding peer dependency npm gives me a warning while trying to resolve: [email protected] ...

Is there a way to stop the initial state in React.js from being regenerated randomly every time I handle an event?

I'm currently developing a game where players take turns attacking each other. Initially, I manually set the player's name and job, then randomly generate their life, damage, and magic attributes in componentWillMount(). My goal is to reduce the ...

Angular component.html does not compile due to a check that includes inline array creation

There is an enum called Status: export enum Status { SOME_VAL = "SOME_VAL", SOME_VAL_2 = "SOME_VAL_2", SOME_VAL_3 = "SOME_VAL_3"; } Also, I have an interface named SomeInterface: export SomeInterface { status? ...

What is the technique for filtering multiple values using the OR operation in ng-model functions?

Currently, I am using an ng-modal labeled as "myQuery." At the moment, there are two filters in place that look like this: <accordion-group heading="" ng-repeat="hungry_pets in Pets" | filter:{hungry:false} | filter:{name:myQuery}" ... > I have ...

How does reactjs distinguish between render and return?

I am a beginner in the world of JavaScript. I often come across the terms "return" and "render" in various contexts, but I'm curious about their differences. ...

Retrieving User Keypad Input with Twilio Phone Calling in a Node.js Application (excluding web server)

const userInput = message.content.split(' ') const phoneNumber = userInput[1] const messageToSay = userInput.slice(2).join(' ') if (phoneNumber) { // Dial phoneNumber and deliver messageToSay, then gather ke ...

Can you determine if a function is a generator function if .bind() has already been applied to it?

It seems like using .bind(this) on a generator function is interfering with determining if the function is actually a generator. Any suggestions on how to resolve this issue? function checkIfGenerator(fn) { if(!fn) { return false; } ...