Iterate over an array of objects to gather and accumulate the information stored within them

I am working with an array that is retrieved from my database, which contains objects. This array includes hours, employee IDs, and a list of employees on the web page. My goal is to display the number of hours assigned to a specific employee when clicking on their name.

var makeup_hrs = api_resp.makeup_data[key];

for (var i = 0; i < makeup_hrs.length; i++) {
  var obj = makeup_hrs[i];
  console.log(obj);
  for (var o in obj) {
    var y = obj[o];
    console.log("make up hours ", y, "id: ", emp_id)

    var x = document.getElementById("makeUpHours").innerHTML = y;
    console.log(x);

    // $('#makeUpHours').html(y);
  }
}

Although I am able to successfully retrieve the number of hours assigned to each employee along with their ID through console logs, I am facing an issue with displaying this information via innerHTML. It only displays the last hours value rather than matching it to a specific employee.

The console output shows data for two employees currently stored in my database:

 make up hours  4 id:  2891
make up hours  7 id:  1978

Below is the relevant HTML code within a Bootstrap modal where the hours information should be displayed:

<div class="form-group">   <label class="col-sm-3"> Hours </label> 
  &nbsp;<span id="makeUpHours"></span></div>

A modal window pops up when an icon is clicked, with each icon corresponding to a specific employee ID.

https://i.sstatic.net/0cL6V.jpg

https://i.sstatic.net/D4XHw.jpg

https://i.sstatic.net/AZAIN.jpg

The correlation between employee IDs and hours is correctly established when these values are logged together.

Answer №1

It is important to note that in each iteration, you are replacing the content of innerHTML instead of adding to it. This means that only the result of the last iteration will be visible.

Consider this alternative approach:

// example data
const employees = [{
  name: 'Alice',
  hours: 8
}, {
  name: 'Mike',
  hours: 12
}, {
  name: 'Sarah',
  hours: 16
}]

const ul = document.getElementById('staff')

// format employee information
const stringifyData = staffMember => `${staffMember.name}: ${staffMember.hours} hours`

// insert employee HTML 
const addStaffMember = text => {
  ul.innerHTML += `<li>${text}</li>`
}

// loop through the array
employees.map(stringifyData).forEach(addStaffMember)
<ul id="staff"></ul>

I personally recommend separating data manipulation from DOM modifications for easier testing purposes, but you can combine both steps within a single iteration if needed.

Answer №2

To gain a deeper understanding of the issue at hand, let's delve into some theoretical concepts. It is crucial to comprehend the underlying problem in order to effectively discover a solution.

Imagine you have an array of objects:

[{
  id: 1,
  x: 10,
}, {
  id: 2,
  x: 20,
}, {
  id: 3,
  x: 30,
}];

You aim to generate the following HTML markup for insertion into the innerHTML property of any DOM element:

<p>id: 1, x: 10</p>
<p>id: 2, x: 20</p>
<p>id: 3, x: 30</p>

(note that there is no common parent element, as this is valid for innerHTML manipulation)

You could iterate through the array of objects using a for loop, then access the properties of each object with another nested for loop. To achieve this, accumulate the desired result outside the scope of these loops but within the function responsible for changing the innerHTML of the target element. Here's a basic implementation:

let result = '';

for (let i = 0; i < array.length; i++) {
  result += `<p>id: ${array[i].id}, x: ${array[i].x}</p>`;
}

element.innerHTML = result;

An alternative approach commonly used in the Javascript community involves leveraging map and reduce functions on collections of similar elements. Implementing this approach would simplify your code to:

element.innerHTML = array.reduce((total, current) => `${total}<p>id: ${current.id}, x: ${current.x}</p>`, '');

While this may appear complex at first glance, it achieves the same outcome efficiently.

Lastly, keep in mind that when concatenating strings, use +=; when replacing its value entirely, utilize =.

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

Issue with div element not stretching to 100% width

I am currently working on a fluid layout design where the template includes a header, menu, and body section. <div class="w100 h100"> <div id="headerBox" style="height: 10%;" class="w100"> <div style="width: 80%;" class="lfloat ...

Steps to deactivate two choices in a multi-select dropdown menu and visually dim those options

Hey there, I recently worked with Angular8 and Bootstrap 4. I utilized a Bootstrap multi-select dropdown, where I encountered an issue: specifically, I'm trying to disable and gray out the options for PL Marketing and CL Marketing but have been unsucc ...

Retrieve JSON information via AJAX

Consider the following JavaScript AJAX request: $.ajax({ type: "POST", url: "/myurl", async: false, data: JSON.stringify({}), contentType: "application/json", complete: function (data) { var ...

Utilize Protractor Selenium to extract content from a popup window

Having trouble capturing the text from a popup using Protractor with getText? The HTML structure can be found here. This popup only appears for a few seconds before disappearing. Can anyone assist me in retrieving the text from this popup? To retrieve the ...

Which JavaScript library or template engine would be most suitable for this scenario?

I am tasked with creating an invite your Facebook friends module that will display the names and photos of your friends, allowing you to message them. It is essential that this feature seamlessly integrates into my website's design, so I need to style ...

I am having trouble getting my website to work offline using caching

My cache file is displayed below: CACHE MANIFEST # 2013-11-22 14:38:54735779 CACHE: ../../../../assets/img/background_01.jpg ../../../../assets/img/background_02.jpg ../../../../assets/img/background_03.jpg ../../../../assets/img/datepicker_icon.png .. ...

The anchor tag is failing to register when placed inside a dynamically created table cell

I'm attempting to place an anchor tag within a cell of an HTML table. Here is the code I am using, but for some reason, the tag is not being identified and no hyperlink is displayed in that cell. Is there an issue with the syntax? $("#tranTbodyI ...

Is there a way to mimic this type of scrolling effect?

Upon visiting this website, it is evident that the entire interface has been constructed with React. The scrolling experience on this site is exceptionally smooth, although it may feel slightly more substantial than a typical scroll. After researching onli ...

Stop unauthorized access to PHP files by utilizing AJAX

Is there a way to prevent direct access to a specific PHP file named prevented.php? My approach involves a main file called index.php, which generates and stores a token in a $_SESSION variable. Additionally, there is another file called def.php that is ac ...

problem with the video pathway in the javascript document

I'm currently in the process of putting together a Video gallery playlist using HTML, CSS, and JavaScript. So far, I've set up the html and css files along with two js files. The first js file contains all the video information as shown here: ...

Utilizing PHP to iterate through an array of MySQL data

Currently, I am developing a roster/calendar system and facing difficulties due to my limited knowledge of PHP arrays. The specific issue at hand involves two date cells labeled 17/08/2017 and 18/08/2017. On these dates, 2 staff members are scheduled on t ...

Displaying an alert message when incorrect login credentials are detected in React Native

My objective is to display an alert message when a user login attempt fails, however, the alert does not appear. Below is the code I am using in React Native: login onPressLogin(){ fetch('http://192.168.1.10:3000/users/login',{ m ...

How can I send back multiple error messages from a pug template in a node.js application with Express?

I am currently working on validating inputs from a form on a Node.js web server using Pug.js and Express.js. The issue I am facing is that when there are multiple problems with the user's input, only the first error is displayed to the user. How can I ...

Combine two arrays at unpredictable locations

Is there a way to combine two arrays in such a manner that one array remains scattered while the other maintains its original order globally? Consider the following example with two arrays: $_array_1 = array( a, b, c ); $_array_2 = array( 1, 2, 3, 4, 5, ...

Achieving Dynamic Center Alignment of Filtered Node in SVG Using D3

I am currently implementing filter functionality for my d3 graph. The goal is to allow users to search for a specific node by label or ID, then re-render the graph to display the entire structure with the filtered node positioned at the center of the SVG e ...

Troubleshooting: JSColor Is Failing to Function Properly in Volusion's

Recently, I've encountered some issues with the JSColor plugin () on the Volusion e-commerce platform. Despite having successfully used it before, getting it to load correctly seems to be a challenge. My current task involves working on a test produc ...

When I adjust the page size, the navbar stays hidden after clicking

Trying to implement a toggle button for the navigation bar. The objective is to hide the navbar on screens smaller than 667px and display a toggle button instead. Clicking the button should toggle the visibility of the navbar items. The toggle button work ...

Is it possible in Angular JS to only load a service in the specific JS file where it is needed, rather than in the app.js file

I attempted to do something like: var vehicle_info = angular.module('psngr.vehicle_info', []).factory('vehicle_info', ['$rootScope', '$timeout', '$q', vehicle_info]); var name = vehicle_info.getNameOfVclas ...

Tips for efficiently showcasing array responses in Vue.js and Laravel

I am looking to showcase array data within a .vue file, but I am uncertain about the process. This is my attempt: <template> <div id="app"> <table class="table table-striped"> <thead> <tr> ...

Achieving Full Height for Parallel Columns Divs with Bootstrap - A How-To Guide

I am struggling with getting two divs in parallel to have full height. Even though I have the divs side by side, when I try to set their height:100%;, nothing happens. What CSS properties do I need to modify to achieve this? The goal is to create a cove ...