notADevYet
notADevYet

Reputation: 327

How to loop over an Array from an API where some properties has null as value, without modifying it

I am practising with vainilla JS, fetching some data from a public API, and manipulating the DOM with them.

I am finding a problem i am not sure how to solve. The object has some null values in some fields , but other times that field contain some information. When I run a loop over it, it always breaks when it reaches one field with a null value.

I would like to know what the best approach should be.

One might be to "clean" the null values from the object, and store the "new cleaned" object in a variable . But guess that´s not the way to go if the API were big.

My second idea would be to include an if condition in the loop, saying to jump to the next one, if the value found is === null , something like this :

function createSomeCards(myObject) {
       for (let i=0; i < myObject.lenght; i++) {
    if (value === null) { i = i+1 } else { i = i }
    here would go the rest of the code to build the cards

i don`t know if that is the approach (even if my code is waz wrong), or should be different. The object has an structure similar to this :

 myObject = [
    {
        "Habitat Impacts": "Area closures ",
        "Image Gallery": [
            {
                "src": "anImage.jpg",
                "alt": "some text",
                "title": "more text"
            },
            {
                "src": null,
                "alt": "additional text",
                "title": "a title here"
            },
            {
                "src": "otherImg.jpg",
                "alt": "imgInfor",
                "title": null
            }      
        ],
        "Management": null,
        "Scientific Name": "Urophycis tenuis",
        "Species Illustration Photo": {
            "src": null,
            "alt": "Illustration",
            "title": ""
        },
        "Ecosystem Services": null,   
        "Servings": "1",
        "last_update": "05/19/2021 - 13:04"
    }]

I update the comment with the JS code in which I am finding the issue with the Null values

function createCards(myObject) {
    let cardContainer = document.getElementById('cardContainer');
    
    for (let i = 0; i < myObject.length; i++) {

    
            
        aInfoButtonLeft.onclick = function () {
            let divSlidAct = document.getElementById('sliderImg')
            let imgSlidAct= document.createElement('img');
            imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][i]['src']);
            imgSlidAct.append(divSliderActive);
        }

    }
}

Upvotes: 1

Views: 1627

Answers (2)

Janos Vinceller
Janos Vinceller

Reputation: 1266

  1. Please change the question title, because you're not looping over an object where there's some null values, but you're looping over an array that only has non-null values in your example. The item of that loop can have a property that is sometimes null. That's a different issue.
  2. You asked about the best approach.

    1. "clean" the null values and store the "new cleaned" object in a variable

      This is not necessary and yes, this would blow up your memory usage and would consume time

    2. include an if condition in the loop, saying to jump to the next one, if the null value found

      if (item.property === null) {
        // jumping to the next item of the loop
        continue;
      }
      
      // do the processing
      

      You can either jump to the next (continue) or you don't do the processing for that item (you do the processing only if not null) like this:

      if (item.property !== null) {
        // do the processing
      }
      
    3. You could even be safer if checking properties by hasOwnProperty() like here: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

    4. I recommend using functional programming and filtering the array by using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter like this - this results in a much clearer code:

      // for this you could also use myObject.forEach(), but that's not the question here
      for (let i = 0; i < myObject.length; i++) {
      
        // filtering image gallery for items that ...
        myObject[i]['Image Gallery'] //
          // have a non-null src
          .filter(item => item.src !== null) //
          // and do for each item that following...
          .forEach(item => {
            console.log('src: ' + item.src); //notice it .src and not ["src"]
            console.log('alt: ' + item.alt);
            console.log('title: ' + item.title);
          });
      }
      

Upvotes: 1

Karakuchi
Karakuchi

Reputation: 1324

I am going to leave my orignal answer under this one because I think it still relevant.

you have an array in an array and you are not looping over the second array "Image Gallery". Adding a second loop lets you get all the images.

I added a check to see if the src was null. this should stop any errors you get about src being null.

function createCards(myObject) {
    let cardContainer = document.getElementById('cardContainer');

    for (let i = 0; i < myObject.length; i++) {

        for (let x=0; x < myObject[i]["Image Gallery"].length; x++) {

                if (myObject[i]['Image Gallery'][x]["src"] === null) {
                    // the source is empty do nothing
                }else{
                    aInfoButtonLeft.onclick = function () {
                    let divSlidAct = document.getElementById('sliderImg')
                    let imgSlidAct= document.createElement('img');
                    imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][x]["src"]);
                    imgSlidAct.append(divSliderActive);
                }
            }
        }
    }
}

ORIGNAL ANSWER

You have 2 1 issue.

  1. you have an array in an array and you are not looping over the second array "Image Gallery"

2. the 'src' field is an attribute of an object and not an index of an array.

The fact that you have null values doesn't matter. the loop will continue.

See the code below with comments.

let myObject = [
{
    "Habitat Impacts": "Area closures ",
    "Image Gallery": [
        {
            "src": "anImage.jpg",
            "alt": "some text",
            "title": "more text"
        },
        {
            "src": null,
            "alt": "additional text",
            "title": "a title here"
        },
        {
            "src": "otherImg.jpg",
            "alt": "imgInfor",
            "title": null
        }      
    ],
    "Management": null,
    "Scientific Name": "Urophycis tenuis",
    "Species Illustration Photo": {
        "src": null,
        "alt": "Illustration",
        "title": ""
    },
    "Ecosystem Services": null,   
    "Servings": "1",
    "last_update": "05/19/2021 - 13:04"
}];

//loop over my object
for (let i=0; i < myObject.length; i++) {

//loop over the image gallery
  for (let x=0; x < myObject[i]["Image Gallery"].length; x++) {
    console.log("src: " + myObject[i]["Image Gallery"][x].src); //notice it .src and not ["src"]
    console.log("alt: " +myObject[i]["Image Gallery"][x].alt);
    console.log("title: " +myObject[i]["Image Gallery"][x].title);
    
    //I commented out this section so the snippet would work 
   /*
    aInfoButtonLeft.onclick = function () {
        let divSlidAct = document.getElementById('sliderImg')
        let imgSlidAct= document.createElement('img');
        imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][x].src);
        imgSlidAct.append(divSliderActive);
   */
    }

  }

Upvotes: 3

Related Questions