6

I'm trying to figure out why the values in my chart are not coming out correctly. When I log the values of learningLanguages[j].count++ as it is looping they are accurate. However, when I log n in the map function in the chart $.map(nativeLanguages, function(n) {...}), the counts are all incorrect (and seemingly arbitrary)

var getLanguages = $.get('/languages.json', function(languages){
        // top level language arrays
        learningLanguages = []
        nativeLanguages = []

        // object constructor that correctly formats the language objects
        function Language(lang) {
            this.language = lang;
            this.count = 0;
        }

        // Loop through the languages, create an object for each, push to top level language arrays
        for(i = 0; i < languages.length; i++) {
            currentLanguage = new Language(languages[i].language)

            learningLanguages.push(currentLanguage)
            nativeLanguages.push(currentLanguage)
        }
     });

    // once the languages call is complete find signed-in user's info
    getLanguages.done(function() {
        $.get('/users.json', function(response) {
            // console.log(response)
            // adds the total number of users to the DOM
            var numberOfUsers = response.length
            $('#userCount').append('<h1>Total Users: ' + numberOfUsers + '</h1>')
            // find the number of approved users
            // var numberApproved = 0
            // for (i = 0; i < response.length; i++) {
            //     if (response[i].approved === true) {
            //         numberApproved++
            //     }
            // }
            // Add the number of approved users to the DOM
            // $('#userCount').append('<h1>Total Approved Users: ' + numberApproved + '</h1>')


            // search for the language in the array and increase the count for that language
            for (i = 0; i < response.length; i++) {
                var userLearningLanguage = response[i].learning_language

                for (j = 0; j < learningLanguages.length; j++) {
                    if (learningLanguages[j].language === userLearningLanguage) {
                        learningLanguages[j].count++
                    }
                }
            }
            // search for the language in the array and increase the count for that language
            for (i = 0; i < response.length; i++) {
                var userNativeLanguage = response[i].native_language
                for (j = 0; j < nativeLanguages.length; j++) {
                    if (nativeLanguages[j].language === userNativeLanguage) {
                        nativeLanguages[j].count++
                    }
                }
            }

            var ctx = $("#languageComparisonChart");
            var myChart = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: 
                        $.map(learningLanguages, function(n) {
                            return n.language
                        }),
                    datasets: [{
                        label: '# of Learners',
                        data:  $.map(learningLanguages, function(n) {
                                return n.count
                            }),
                        backgroundColor: 'rgba(255, 99, 132, 0.2)',
                        borderColor: 'rgba(255,99,132,1)',
                        borderWidth: 1
                    },
                    {
                        label: '# of Native Speakers',
                        data:  $.map(nativeLanguages, function(n) {
                            console.log(n)
                                return n.count
                            }),
                        backgroundColor: 'rgba(54, 162, 235, 0.2)',
                        borderColor: 'rgba(54, 162, 235, 1)',
                        borderWidth: 1
                    }]
                },
                options: {
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero:true
                            }
                        }]
                    },
                    responsive: false,
                    maintainAspectRatio: true
                }
            });
        })
    });
}   
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
user3006927
  • 484
  • 4
  • 15
  • Have you tried to log right after the `for` loop? Or just inside it? – Diego Cardoso Sep 30 '16 at 20:32
  • Is this all the code?, as there are lots of errors here. eg. your using variables without defining them. You not using any hinting?.. Also indenting is all wrong, and you have an extra } – Keith Sep 30 '16 at 20:41
  • And you should use semi-colons to terminate lines - see [answers here](http://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascript) – Sᴀᴍ Onᴇᴌᴀ Sep 30 '16 at 20:51
  • @Aelliott1485 they are optional and some minifiers now will even account for them missing. it is best practice but isn't causing a problem here – charlietfl Sep 30 '16 at 20:54

2 Answers2

7

Part of your problem stems from pushing the same object into the 2 different arrays here:

    for(i = 0; i < languages.length; i++) {
        currentLanguage = new Language(languages[i].language)

        learningLanguages.push(currentLanguage)
        nativeLanguages.push(currentLanguage)
   }

This does not copy currentLanguage into each, it pushes references of the same object into each.

Then whatever you do to that object reference in one will be reflected in the other

Try making 2 separate objects

    for(i = 0; i < languages.length; i++) { 
        learningLanguages.push(new Language(languages[i].language))
        nativeLanguages.push(new Language(languages[i].language))
   }

the use of global variables will also get you into trouble...don't do it!

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • Thank you! This definitely was an issue. The count values were the same for each language in each array because they were references. Thanks for your help! – user3006927 Oct 02 '16 at 14:15
1
learningLanguages = []
nativeLanguages = []

These two variables look like they are not defined in an above scope - thus the second XHR call does not know about these variables.

Second piece of the answer is reference to the same object instance, with the same "count" attribute touched twice.

I'd suggest two options are here:

  • use new Language(...) for each of these two arrays separately
  • or have a separate counter for each type of native/learning counts.
Jakub Koral
  • 368
  • 4
  • 10
  • Thanks for this response! I moved those two arrays out of the first ajax call and I am using var for both of them so they are no longer global variables – user3006927 Oct 02 '16 at 14:24