Home > Blockchain >  Uncaught TypeError: Cannot read properties of undefined (reading 'CountOf') from my sql qu
Uncaught TypeError: Cannot read properties of undefined (reading 'CountOf') from my sql qu

Time:01-05

I have a table in database with the emotion field which can currenlty store max 7 emotion of a human face 'angry','disgusted','fearful,'happy','neutral','sad','surprised'. I want to create a chart through my sql query. I want to count the number of emotion with the same userid and show it in chartjs. and after successful get data returned through ajax call I am able to create a chart only if all emotions are stored in table for example if no entry for fearful emotion I am getting this error, how I can prevent this error for the emotion with no entry.

`function generategraph(angry,disgusted,fearful,happy,neutral,sad,surprised){
        if(myChart!=null)
        {
            myChart.destroy();
        }
            myChart = new Chart (ctx, {
                type: 'bar',
                data: {
                    labels: ['Angry', 'Disgusted', 'Fearful', 'Happy', 'Neutral', 'Sad', 'Surprised'],
                    datasets: [{
                        label: '# of Votes',
                        data: [angry, disgusted, fearful, happy, neutral, sad, surprised],
                        borderWidth: 1
                    }]
                },
                options: {
                    scales: {
                        y: {
                            beginAtZero: true
                        }
                    }
                }
            });
    }`

Above is my chart function where I am passing 7 emotions as variable

below is my ajax returned data

0
: 
{emotion_state: 'angry', CountOf: '34'}
1
: 
{emotion_state: 'disgusted', CountOf: '11'}
2
: 
{emotion_state: 'happy', CountOf: '35'}
3
: 
{emotion_state: 'neutral', CountOf: '337'}
4
: 
{emotion_state: 'sad', CountOf: '54'}
5
: 
{emotion_state: 'surprised', CountOf: '61'}
length
: 
6
[[Prototype]]
: 
Array(0)

Here is the code where I am calling the function

if(this.readyState === 4 && this.status === 200) {
        var data = JSON.parse(this.responseText);
        console.log(data);
        // Inserting the response from server into an HTML element
        generategraph(data[0].CountOf,data[1].CountOf,data[2].CountOf,data[3].CountOf,data[4].CountOf,data[5].CountOf,data[6].CountOf)

Do I need to make an array from ajax request and compare or set default 0 if no countof? if yes please guide little bit as I am new Thanks

I need to show all emotions count even if it zero how it is possible if emotion count is zero because if I select unique values through my sql query it will make count and return the emotions which are available in database.

CodePudding user response:

instead of sending each count to the function and hardcoding the list of emotions in chart, you can try doing following

Create object containing all possible emotions with initial default value as 0.

const emotions = {
    angry: 0,
    disgusted: 0,
    fearful: 0,
    happy: 0,
    neutral: 0,
    sad: 0,
    surprised: 0
}

your response from AJAX looks something like this right,

const response = [
    {emotion_state: 'angry', CountOf: '34'},
    {emotion_state: 'disgusted', CountOf: '3'},
    {emotion_state: 'fearful', CountOf: 0},
    .
    .
]

after the ajax response you can update your emotions object with count like below

for (const item of response) {
    if (emotions.hasOwnProperty(item.emotion_state)) {
        emotions[item.emotion_state] = item.CountOf
    }
}

then pass it to the graph function like below

generategraph(Object.entries(emotions))

and then update your function to handle your inputs like

function generategraph(input){
        if(myChart!=null)
        {
            myChart.destroy();
        }
            myChart = new Chart (ctx, {
                type: 'bar',
                data: {
                    labels: input.map(i => i[0].charAt(0).toUpperCase()   i[0].slice(1)),
                    datasets: [{
                        label: '# of Votes',
                        data: input.map(i => i[1]),
                        borderWidth: 1
                    }]
                },
                options: {
                    scales: {
                        y: {
                            beginAtZero: true
                        }
                    }
                }
            });
    }
  • Related