0

I have a created an accordion that has 7 different categories (Auto, Entertainment, Health and Beauty, etc). The content of each category lives in a SP2013 List; each list item was given the respective category (Auto, Entertainment, Health and Beauty, etc). The main idea is to filter that content by category and inject the item into its respective category enter image description here

This is a piece of the HTML code:

<div id="entertainment" class="accordion-content list-reset leading-normal px-8 py-4 hidden">
<!--Entertainment Content Injected-->
</div>

This is the JS code I have developed so far

$(document).ready(function () {
  $.ajax({
    url: "http://bc-net/_api/web/lists/GetByTitle('specialDiscounts')/items",
    method: 'GET',
    headers: {
      'Accept': 'application/json; odata=verbose'
    },
    success: function (data) {
      var items = data.d.results
      console.log(items)

      var categories = [];
       const auto = document.getElementById('automotive');
       const entertainment = document.getElementById('entertainment');
       const healthBeauty = document.getElementById('healthBeauty');

      for (var j = 0; j < items.length; j++) {

        var categoriesFromSharePoint = items[j].Category;
        console.log(categoriesFromSharePoint);
        categories.push(categoriesFromSharePoint);

      }

     categories.forEach(function (categoryName) {

        if (categoryName === 'Automotive') {
                var paragraph = document.createElement("p");
                paragraph.innerText = items[j].Title;
                auto.appendChild(paragraph);

         } if (categoryName === 'Entertainment') {

                var paragraph = document.createElement("p");
                paragraph.innerText = items[j].Title;
                entertainment.appendChild(paragraph);

                } if (categoryName === 'Health and Beauty') {

                var paragraph = document.createElement("p");
                paragraph.innerHTML = "Health";
                healthBeauty.appendChild(paragraph);
                }
      })

      },
    error: function (data) {
      alert('Error: ' + data)
    }
  }) // End Service Icons  //End Service Icons
}) // End ready function

The above code gives me undefined when trying to acces the Title property from the item.

0

Part of the problem is that your categories.forEach() loop runs after the for (var j...) loop is completely finished. When that loop is done, the value of j is items.length, because that's the condition that ends the loop. So then when you try to index into your items array again, the value of j is too high, so it's giving you undefined.

array[array.length] will always be unreachable, because in Javascript, arrays use zero-based indexing (first one is zero, i.e. array[0]), and by it's very nature length is a count of all the items in the array and counting is 1-based (first one is...one), so array.length will always be to high of a number (by exactly one) to use as an indexer.

In addition, your code could be simplified by not "collecting" all the Category values into a categories array. This likely isn't doing what you think it's doing anyway, since it looks like you maybe are trying to get a distinct list of the categories, but the way your code is set up right now you could potentially end up with

['Automotive', 'Health and Beauty', 'Automotive', 'Entertainment', 'Entertainment', 'Health and Beauty', ...]

depending on what the actual values are on the list items. Since you are mainly using the Category value to determine what section to put the new elements in, and you have several possible values, instead of using sequential ifs, you could consider using a switch statement instead, and put that inside the for loop where you have valid index values for your items array.

So something like:

for (var j = 0; j < items.length; j++) {

    // you're doing this the same for all items,
    // so just write it once, no need to have it
    // repeated in each of the if statements or cases

    var paragraph = document.createElement("p");
    paragraph.innerText = items[j].Title;

    // here is where you want to have branching logic,
    // to append the <p> in different places based on
    // different possible Category values

    switch (items[j].Category) {
        case 'Automotive':
            auto.appendChild(paragraph);
            break;
        case 'Entertainment':
            entertainment.appendChild(paragraph);
            break;
        case 'Health and Beauty':
            healthBeauty.appendChild(paragraph);
            break;
        default:
            break;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.