0

So after pulling all the information from my sql tables, I put them into 2 variables called response1 and response2.Shown below are what's currently inside the arrays. My goal is to display the pictures, beside each student. If a picture doesn't exsist, it can just be blank for now. So i've gotten the picture from DB to display by using base64 encode, but i'm only currently doing it for the id:20000001, since i'm not sure how to do it for other ones.

I had an idea to maybe replace

student_image= findItemByID(response2,'20000001'); 

with

student_image= findItemByID(response2,element.id); ?
but not sure if this is correct logic?

Inside my Object.keys final loop, how should I fix html+='<img src="data:image/jpeg;base64,'+student_image.photo+'">' so that it adds the image of the specific id?

Response1 array of object:

0: {Class_Student_Group: 1, names: "Lastname1, Firstname1", id: 20000001}
1: {Class_Student_Group: 2, names: "Lastname2, Firstname2", id: 20000002}
2: {Class_Student_Group: 3, names: "Lastname3, Firstname3", id: 20000003}
3: {Class_Student_Group: 5, names: "Lastname4, Firstname4", id: 20000004}
4: {Class_Student_Group: 3, names: "Lastname5, Firstname5", id: 20000005}

Response2 array of objects:

0: {student_id: "20000001", photo: ""}
1: {student_id: "20000001", photo: "/9j/4AAQSkZJRgABAQAAAQABAAD/4QB6RXhpZgAASUkqAAgAAA…9a1EtFKAnd09f/rVlwfdFbVw7LPIoOAGNYwjc/SIaxR//2Q=="}
2: {student_id: "20000002", photo: ""}
3: {student_id: "20000003", photo: ""}

final:

1: Array(4)
0: {Class_Student_Group: 1, names: "Lastname1, Firstname1", id: 20000001}
1: {Class_Student_Group: 1, names: "Lastname9, Firstname9", id: 20000009}
2: {Class_Student_Group: 1, names: "Lastname15, Firstname15", id: 20000015}
3: {Class_Student_Group: 1, names: "Lastname19, Firstname19", id: 20000019}
length: 4
__proto__: Array(0)
2: (4) [{…}, {…}, {…}, {…}]
3: (4) [{…}, {…}, {…}, {…}]

output so far:

enter image description here

<script type="text/javascript">





$(document).ready(function() {



var response= <?php echo json_encode($table); ?>;
var response2= <?php echo json_encode($result); ?>;





function findItemByID(arr, id) {
  return arr.find((photoObj) => {
    return photoObj.photo.trim().length !== 0 && photoObj.student_id === id
  })
}


var final = {}

response.forEach(function(element) {
  final[element.Class_Student_Group] = final[element.Class_Student_Group] || [];
  final[element.Class_Student_Group].push(element);

});




let student_image =''


Object.keys(final).forEach(function(Group) {

      let html = '';

      //add the table opening tag to the html variable
      html += '<table>';
      //Append the 'category' header
      html += '<tr>';
      html += '<td><h1>'+"Group"+ Group+'</h1></td>';
      html += '</tr>';

      // Loop through the results for this 'category'
      student_image= findItemByID(response2,'20000001');
      final[Group].forEach(function(element) {   
      var randomImage = images[Math.floor(Math.random() * images.length)];
        var names = element.names;
        var id=element.id;

        var img = "<img src=' " + randomImage+ " ' />";
        html += '<tr>';
        html += '<td><p>' + names + '</p></td> ';
        html += '<td><p>' + id + '</p></td> ';
        html+='<img src="data:image/jpeg;base64,'+student_image.photo+'">'


        html += '</tr>';
      });
      //add the table closing tag to the html variable
      html += '</table>'; 

      $('#tables_container').append(html);
});








});

</script>
miken32
  • 42,008
  • 16
  • 111
  • 154
encrypt
  • 267
  • 1
  • 3
  • 13
  • 1
    Links, images and screenshots can be a nice addition to a post, but please make sure the post is still clear and useful without them. **Don't post images of or links to code, data or error messages.** Instead copy and paste or type the actual code/data/message into the post directly. Please [edit] your question. – rsjaffe Dec 01 '18 at 20:30
  • removed pics and edited question. Thanks – encrypt Dec 01 '18 at 20:40
  • Just a note that `+` is a valid character in base 64, but is not a valid character in a URI. so you should be sure to use `document.encodeURI()` on the data before trying to inject it into HTML code. – miken32 Dec 02 '18 at 05:14

2 Answers2

2

OK. Quite a few things going on here.

  1. Basically the reason(s) the findItemByID() function wasn't working was because A. (and I have to assume you knew this) you were passing in the same ID every time it was called, B. by putting it before you called final[Group].forEach(function(element) you couldn't pass in the right value for the id, as the id is a property of that element variable, and C. === is a strict equality operator, which means it only returns true if the values are the same and they are the same type. In one array of objects that value is a string and in the other it's a number.
  2. You are doing a lot of things out of order. Take a step back and try to think about what this code is intended to do and write it one step at a time, and break your steps into functions whenever practical like I have done here. Look over the changes I have made to your code, and the comments I added. Generally when writing code you want to use functions to make things more readable, and break them apart so you are dealing with the least amount of complexity as possible at any given time. A table works like table - > row - > column -- write your code that way.
  3. I don't know anything about using Base64 for images in HTML, but a look at this link suggests that the data you have supplied here won't work. Check out the decoder in the accepted answer.
  4. I changed the way you were iterating over your final object. This is probably mostly a matter of taste, but to me it's more readable. You can learn more about it here
  5. Use better names! It's so much easier when you're trying to figure out why something is broken if you aren't also trying to remember what data is in response vs response2. Just call them studentDataArray and imageDataArray or something.

$(document).ready(function () {
    loadTable();
});

let array1 = [
    { Class_Student_Group: 1, names: "Lastname1, Firstname1", id: 20000001 }
    , { Class_Student_Group: 2, names: "Lastname2, Firstname2", id: 20000002 }
    , { Class_Student_Group: 3, names: "Lastname3, Firstname3", id: 20000003 }
    , { Class_Student_Group: 5, names: "Lastname4, Firstname4", id: 20000004 }
    , { Class_Student_Group: 3, names: "Lastname5, Firstname5", id: 20000005 }
]

let array2 = [{ student_id: "20000001", photo: "" }
    , { student_id: "20000001", photo: "/9j/4AAQSkZJRgABAQAAAQABAAD/4QB6RXhpZgAASUkqAAgAAA…9a1EtFKAnd09f/rVlwfdFbVw7LPIoOAGNYwjc/SIaxR//2Q==" }
    , { student_id: "20000002", photo: "" }
    , { student_id: "20000003", photo: "" }];

function findItemByID(arr, id) {
    return arr.find((photoObj) => {
        return photoObj.photo.trim().length !== 0 && photoObj.student_id == id // because the id property in the student object is a number and in the photo array it's a string, change this to '==', which evaluates '2' as equal to 2. === only returns true if they are the same type
        //also you have been checking for a student_id property here, which doesn't exist on the second array's objects, so this wasn't returning anything
    })
}

function getFinalObject(response) {
    var final = {}

    response.forEach(function (element) {
        final[element.Class_Student_Group] = final[element.Class_Student_Group] || [];
        final[element.Class_Student_Group].push(element);

    });

    return final;

}

function appendHtmlToDoc(final, response2, images) {

    let html = '';

    //add the table opening tag to the html variable
    html += '<table>';

    for (let Group in final) {               //this will loop through final's properties, in this case, the 'groups'
        if (final.hasOwnProperty(Group)) {    //use hasOwnProperty to make sure you aren't looping through irrevelant properties (https://stackoverflow.com/questions/8312459/iterate-through-object-properties)

            //Append the 'category' header
            html += '<tr>';
            html += '<td><h1>' + "Group" + Group + '</h1></td>';
            html += '</tr>';

            // Loop through the results for this 'category'
            final[Group].forEach(function (element) { //you already have the Group array in the Group variable

                let student_image = findItemByID(response2, element.id);    //search for the image data using this element's id property

                // var randomImage = images[Math.floor(Math.random() * images.length)]; //should pass 'images' into this function, but I don't know where it came from and randomImage/img isn't used in the code you provided, so I removed it
                var names = element.names;
                var id = element.id;

                // var img = "<img src=' " + randomImage + " ' />";
                html += '<tr>';
                html += '<td><p>' + names + '</p></td> ';
                html += '<td><p>' + id + '</p>';
                if (student_image) { //check if something was returned when you searched for the photo, otherwise you'll have a blank image here
                    html += '<td><img src="data:image/jpeg;base64, ' + student_image.photo + '"></td>'; //I don't know anything about using images in HTML with base64, but a look at this link (https://stackoverflow.com/questions/8499633/how-to-display-base64-images-in-html) suggests that what you have provided won't work
                }
                //I also added a td around your img tag

                html += '</tr>';
            });
        }
    }

    //add the table closing tag to the html variable
    html += '</table>';
    //console.log(html)
    $('#tables_container').append(html);

}

function loadTable() {

    //move your php script calls here

    let finalObj = getFinalObject(array1);
    appendHtmlToDoc(finalObj, array2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tables_container"></div>
Katie.Sun
  • 711
  • 3
  • 15
  • There's nothing wrong with their use of a data URI for the image, the syntax is correct as long as the data is a valid base64 encoded image. (That question you linked to is... well it's certainly interesting. Not sure how that answer got 400 votes by basically copying the question.) But, the rest of your points are good. – miken32 Dec 02 '18 at 05:04
  • @miken32 thanks... I had never seen that before, although it's an interesting concept. was just looking at the mdn docs on it – Katie.Sun Dec 02 '18 at 05:08
  • Thank you so much! the issue was with the === in the function, i changed it to = and i put element.id inside my function!! my only question is, so I have an upload picture function on my UI, where users can pick jpeg or png or jpg, and it's stored as a blog. Can i just leave this line "data:image/jpeg;base64? or do I have to include all options like jpeg/jpg/png;base64 – encrypt Dec 03 '18 at 16:23
  • ya so right now it displays with jpeg becuase i uploaded a jpeg, burt im wondering if someone uploads a png or something, will it still work? – encrypt Dec 03 '18 at 19:59
0

Try:

if(!photo.id) {
   // There's no image
} else {
   // There's an image
}
demostanis
  • 88
  • 3
  • 10
  • I need help with my logic inside my Object.keys for loop. Will my html+= only append the specific image for that specific id? I don't want the same photo on every student obviously, and so far my DB only has 1 image ( for id 20000001) so im just testing it for this but obviously each id will have its own image eventually – encrypt Dec 01 '18 at 20:35
  • 1
    If you need to clarify your question, [edit] the original question. – rsjaffe Dec 01 '18 at 20:37