Why does my chartData output [Object], [Object] instead of { label: ‘Lukáš’, value: 8 } in JavaScript?

I’m working on a JavaScript project where I generate a list of employees and their respective work hours. I want to create a chart data object with the names and values of employees, but when I log the chartData, it outputs something like this:

chartData: {
  all: [
    [Object], [Object],
    [Object], [Object],
    [Object], [Object],
    [Object], [Object],
    [Object], [Object]
  ]
}

Instead of the expected output, which should look like this:

chartData: {
  all: [
    { label: 'Lukáš', value: 8 },
    { label: 'Eva', value: 8 },
    { label: 'Tomáš', value: 7 },
    { label: 'Anna', value: 6 },
    { label: 'Lucie', value: 5 },
    { label: 'Jan', value: 4 },
    { label: 'Petr', value: 4 },
    { label: 'Tereza', value: 3 },
    { label: 'Michal', value: 3 },
    { label: 'Jana', value: 2 }
  ]
}

I checked the nameCounter function, and it seems to be counting the names correctly.

I used Object.entries and .map to convert the counts to the required format.

I logged the result, but the output is still in the [Object], [Object] format, which makes me think that the issue might be with how I’m logging the result or how the data is being returned.

heres my code:

// Array of male names
const maleNames = [
    "Peter", "John", "Michael", "Luke", "Thomas"]
// Array of female names
const femaleNames = [
    "Anna", "Jane", "Eva", "Lucy", "Teresa"]
// Array of male last names
const maleLastname = [
    "Smith", "Johnson", "Brown", "Taylor", "Anderson"]
// Array of female last names
const femaleLastname = [
    "Smith", "Johnson", "Brown", "Taylor", "Anderson"
]

/**
 * Main function to generate a list of employees based on input parameters.
 * @param {object} dtoIn - Input object with parameters.
 * @param {number} dtoIn.count - The number of employees to generate.
 * @param {object} dtoIn.age - The age range of the employees.
 * @param {number} dtoIn.age.min - Minimum age of employees.
 * @param {number} dtoIn.age.max - Maximum age of employees.
 * @returns {Array<object>} - An array of objects representing the employees.
 */
function generateEmployeeData(dtoIn) {
    const dtoOut = [];
    for (let i = 0; i < dtoIn.count; i++) {
        let gender = getGender();  // Randomly select gender
        let employee = {
            gender: gender,
            birthdate: getBirthdate(dtoIn.age.min, dtoIn.age.max),
            name: getName(gender, maleNames, femaleNames),  // Get the name based on gender
            surname: getName(gender, maleLastname, femaleLastname),  // Get the surname based on gender
            workload: getWorkload()  // Randomly select workload
        }
        dtoOut.push(employee);
    }

    // Sort employees by their workload in ascending order
    return dtoOut.sort((a, b) => a.workload - b.workload);
}

/**
 * Randomly generates a number within the given range.
 * @param {number} min - The minimum value.
 * @param {number} max - The maximum value.
 * @returns {number} - A random number between min and max (inclusive).
 */
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

/**
 * Randomly determines the gender.
 * @returns {string} - "male" or "female".
 */
function getGender() {
    return getRandom(0, 1) === 0 ? 'male' : 'female';
}

/**
 * Generates a random birthdate based on the given age range.
 * @param {number} ageMin - Minimum age.
 * @param {number} ageMax - Maximum age.
 * @returns {string} - Birthdate in ISO 8601 format.
 */
function getBirthdate(ageMin, ageMax) {
    const currentDay = new Date().getTime();
    const yearInMil = 365.25 * 24 * 60 * 60 * 1000;

    const minRange = currentDay - (new Date(ageMax * yearInMil));
    const maxRange = currentDay - (new Date(ageMin * yearInMil));
    const birthDate = getRandom(minRange, maxRange);

    return new Date(birthDate).toISOString();
}

/**
 * Returns a random name based on gender.
 * @param {string} gender - Gender ("male" or "female").
 * @param {Array<string>} male - Array of male names.
 * @param {Array<string>} female - Array of female names.
 * @returns {string} - A random name corresponding to the gender.
 */
function getName(gender, male, female) {
    return gender === 'male' ? male[getRandom(0, male.length - 1)] : female[getRandom(0, female.length - 1)];
}

/**
 * Generates a random workload (work hours) from a list of possible values.
 * @returns {number} - Random workload (e.g., 10, 20, 30, 40).
 */
function getWorkload() {
    const workloads = [10, 20, 30, 40];
    const index = getRandom(0, workloads.length - 1);
    return workloads[index];
}

/**
 * Extracts all names from a list of employees.
 * @param {Array<object>} list - List of employees.
 * @returns {Array<string>} - Array of employee names.
 */
function getAllNames(list) {
    return list.map(e => e.name);
}

/**
 * Filters the list by gender and returns only employees of the specified gender.
 * @param {Array<object>} list - List of employees.
 * @param {string} gender - The gender to filter by ("male" or "female").
 * @returns {Array<object>} - Filtered list of employees by gender.
 */
function getNameByGender(list, gender) {
    return list.filter(e => e.gender === `${gender}`);
}

/**
 * Filters the list by gender and workload (full-time or part-time).
 * @param {Array<object>} list - List of employees.
 * @param {number} [workload] - If provided, filters by a specific workload.
 * @returns {Array<string>} - List of names that match the criteria.
 */
function genderWorkload(list, workload) {
    if (workload === undefined) {
        let femaleList = getNameByGender(list, "female");
        femaleList = femaleList.filter(e => e.workload !== 40);  // Part-time female employees
        return getAllNames(femaleList);
    }
    else {
        let maleList = getNameByGender(list, "male");
        maleList = maleList.filter(e => e.workload === 40);  // Full-time male employees
        return getAllNames(maleList);
    }
}

/**
 * Counts the occurrences of names in a list.
 * @param {Array<string>} list - List of names.
 * @returns {object} - An object with the name counts.
 */
function nameCounter(list) {
    return list.reduce((acc, name) => {
        acc[name] = (acc[name] || 0) + 1;
        return acc;
    }, {});
}

/**
 * Converts the name counts into the required format { label, value } and sorts by value.
 * @param {Array<string>} list - List of names.
 * @returns {Array<object>} - Array of objects with the format { label: name, value: count }.
 */
function charOutput(list) {
    const countedNames = nameCounter(list);
    return Object.entries(countedNames).map(([label, value]) => ({
        label: label,
        value: value
    })).sort((a, b) => b.value - a.value);  // Sort by value descending
}

/**
 * Creates chart data with name counts for all employees, male, and female.
 * @param {Array<object>} list - List of employees.
 * @returns {object} - Object containing chart data for all employees, male and female.
 */
function getEmployeeChartContent(list) {
    const dtoOut = {
        names: {
            all: nameCounter(getAllNames(list)),  // Dynamic creation for 'all'
            male: nameCounter(getAllNames(getNameByGender(list, "male"))),
            female: nameCounter(getAllNames(getNameByGender(list, "female"))),
            femalePartTime: nameCounter(genderWorkload(list)),
            maleFullTime: nameCounter(genderWorkload(list, 40)),
        },
        chartData: {
            all: charOutput(getAllNames(list)),
            male: charOutput(getAllNames(getNameByGender(list, "male"))),
        }
    };
    return dtoOut;
}

/**
 * The main function to generate employee data and chart content.
 * @param {object} dtoIn - Input parameters.
 * @returns {void}
 */
function main(dtoIn) {
    let data = generateEmployeeData(dtoIn);
    const dtoOut = getEmployeeChartContent(data);
}

// Example input data for employee generation
const dtoIn = {
    count: 50,
    age: {
        min: 19,
        max: 35
    }
}

// Generate employee data and display the chart content
let data = generateEmployeeData(dtoIn);
console.log(getEmployeeChartContent(data));

// Output the name count in the required chart format
console.log(charOutput(getAllNames(data)));