Unable to loop array data

I got this value below from MySQL using php.

$data = "{"0":{"Ama":"100", "Jim":"80"},"1":{"Ama":"30","Jim":"100" }, "2":{"Ama":"50", "Jim":"100"}, "class": "upper","status":"active"}"

and I want to loop through it with JavaScript and get individual values into a table

Like :

<td>data.Ama<td><td>data.Jim<td>
<td>data.Ama<td><td>data.Jim<td>
 <td>data.class<td><td>data.status<td>

It returns undefined and says it’s not an array rather a string.
If I use JSON.parse it returns an Object yet unable to loop through.

If I use foreach loop it says not a function.

Any help?

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

1 Like

Thanks You KevinSmith👍

Something like this would work, to get the data in the right format:

const data = {
  "0": {
    Ama: "100",
    Jim: "80",
  },
  "1": {
    Ama: "30",
    Jim: "100",
  },
  "2": {
    Ama: "50",
    Jim: "100",
  },
  class: "upper",
  status: "active",
};

const { class: classLevel, status, ...studentObject } = data
const students = Object.values(studentObject)

console.log(classLevel)
// upper

console.log(status)
// active

console.log(students)
// [
//   { Ama: "100", Jim: "80" },
//   { Ama: "30", Jim: "100" },
//   { Ama: "50", Jim: "100" }
// ]

That assumes that the students are in the right order. I assume that studentObject is an array like object but couldn’t get it to work. I might also map through the data and convert the grades to numbers. Often I have a “transform” function in my service layer where I will transform the data to the shape that I want.

1 Like

This worked like charm, :smiling_face_with_three_hearts: but when I loop through the students data with their keys for it’s values I get the data also getting undefined at the end of the response.

I think it returns the – class and status --values as undefined while fetching the students data too.

Any help?

Can you show your latest code and exactly what you were able to shape the data into?

1 Like

Below is my code:

 Object.keys(students).forEach(function(key, index){
                console.log(students[key].tip);
                html += " <tr><td>"+students[key].Ama+"</td>" +
                "<td>"+students[key].Jim+"</td>" +
                "<td>"+students[key].Ama+"</td>" +
                "<td>"+students[key].Jim+"</td>" +
            "</tr>" ;
            })

From the students data while on loop it returns undefined values at the end after returning the actual data. like this:-
Ama: “100”,
Jim: “80”,
Ama: “30”,
Jim: “100”,
undefined,
undefined.

into the table.

maybe because there are these two entries at the end that have no Ama / Jim properties?

1 Like

Yes, that’s what I can say, but I don’t know why it keeps getting the values even when am not fetching it’s keys.

You have not really explained what the data represents. For example, the 3 inner objects with the 0 - 2 keys, are each of these a class grade for each person or all they all grades from the same class for say different assignments?

  0: { Ama: "100", Jim: "80" },
  1: { Ama: "30", Jim: "100" },
  2: { Ama: "50", Jim: "100" },

I ask, because I am not understanding how the class and status are related to the 3 objects containing Ama and Jim properties.

Anyway, when you use Object.keys(), the keys in this object are:
0, 1, 2, class, and status, so only the first 3 keys (0, 1, and 2) are going to have an Ama and Jim, since only the first 3 keys are for objects. The last 2 keys are class and status whose property values are text. That is why you are seeing the extra undefined values for the last two keys.

What are you ultimately trying to do with this data? What does your desired table output look like?

1 Like

Okay, the class and status data are being merged with the students data from my mysql php into one data

students=array_merge(students, class,status);

Then am using JavaScript to display the values on a table.

It should look like this:-

name. Score
Ama 100
Jim. 80
Ama 50
Jim. 100

Then a button to display status and class in a different div after the table has been created.

But instead am getting:

name. Score
Ama 100
Jim. 80
Ama 50
Jim. 100
unidentified unidentified
unidentified unidentified

Can you put an echo students; on the next line after students=array_merge(students, class,status); and show us what gets displayed?

Also, if you are still using the same code as shown above with the forEach, you are going to have the same problem as I already explained about the undefined values. If you have changed your code, please post that also.

One last thing, you originally showed us an object that had 3 nested objects:

  0: { Ama: "100", Jim: "80" },
  1: { Ama: "30", Jim: "100" },
  2: { Ama: "50", Jim: "100" },

Wouldn’t you want to display the following instead?

Name Score
Ama 100
Jim 80
Ama 30
Jim 100
Ama 50
Jim 100

If the above is correct, then do not merge the class, and status onto students. That way, you will only get the above results.

1 Like

Yes if I don’t merge the Class and status data I will get this:

0: { Ama: "100", Jim: "80" },
  1: { Ama: "30", Jim: "100" },
  2: { Ama: "50", Jim: "100" },

But I need to get the students data along with the class and status data so that it will be displayed on the front end each time a new student data Is fetched from the db.

This is how my data looks like on console.log:

When I merge the array students with class and status:

{
"0": { "Ama": "100", "Jim": "80" },
  "1": { "Ama": "30", "Jim": "100" },
  "2": { "Ama": "50", "Jim": "100" },
  "3":  "Class": "upper",
  "4": "Status": "active"
 }

This is how it looks without the array merge.

{
"0": { "Ama": "100", "Jim": "80" },
  "1": { "Ama": "30", "Jim": "100" },
  "2": { "Ama": "50", "Jim": "100" },
 }

I did not see any code that displays the class or status, so I was not sure what you needed it for.

Also, the following is not valid syntax for an object.

  "3":  "Class": "upper",
  "4": "Status": "active"

Assuming your data looks more like:

const students = {
  "0": {
    Ama: "100",
    Jim: "80",
  },
  "1": {
    Ama: "30",
    Jim: "100",
  },
  "2": {
    Ama: "50",
    Jim: "100",
  },
  class: "upper",
  status: "active",
};

and since I assume there may be other student names and scores that could come through at some point, I would recommend something like:

let html = '';
Object.keys(students).forEach(function(key){
  if (key !== 'class' && key !== 'status') {
    const student = students[key];
    Object.keys(student).forEach(function(studentName) {
      html += `<tr><td>${studentName}</td><td>${student[studentName]}</td></tr>`;
    });
  }
});

OR using Object.entries():

let html = "";
Object.entries(students).forEach(function ([key, value]) {
  if (key !== "class" && key !== "status") {
    Object.entries(value).forEach(function ([studentName, score]) {
      html += `<tr><td>${studentName}</td><td>${score}</td></tr>`;
    });
  }
});
1 Like

Yaah! This worked! Thank You Very Much!