0

I have two arrays that I am using to simulate two different REST call's JSON response for the time with some static data. One to get the available active categories and another to get all links and then search to find what links go with what category.

The goal here is to build out a navigation that will take each category and display the corresponding links underneath each.

Currently I am unable to get the category to display only once and above the links related to each category then draw the output to the dom once complete.

I tried to use $.one but that did not work. Does anyone have any pointers or suggestions to nudge me in the right direction?

var links = [
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com"
    },
    "Id": 01,
    "Title": "Link 01 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 01
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 02,
    "Title": "Link 02 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 02
  },
  {

    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 03,
    "Title": "Link 01 - test category 02",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 209
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 210,
    "Title": "Link 02 - test category 02",
    "Link": "https://www.somerandomdomain.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 210
  }
]

//category arr
var categoryArr = [
  "Test Category 01",
  "Test Category 02",
  "Test Category 03"
]

var categoryTitle;
var menu = $("#output2");

    $.each(categoryArr, function (catIndex, category) {

      $.each(links, function(linkIndex, links) {
        
           if(links.Category.results == category) {

    	          // DOM ELEMENTS
                var item = $('<div>').addClass('navContainer'),
                    title = $('<h4>'),
                    info = $('<p>'),
                    link = $('<a>');
                    
								// CATEGORY TITLE

                info.text(categoryArr[catIndex]); // not showing once per iteration.

                // ADD LINKS
                link.attr('href',links.Link)
                .text(links.Title)
                .appendTo(title);

                // ADD EVERYTHING
                item.append(info,title);

                // DISPLAY TO CONTAINER
                item.appendTo(menu);
           }
        
    	})// end glinks


    }) // end categoryArr
.navContainer {
  border: 1px solid grey;
  margin: 10px;
  padding:5px;
}
.links ul li { 
  list-style-type:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
 Result should look like this below
</h5>
<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
  <ul>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  </ul>
  </div>
</div>  
</div>

<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
  <ul>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  </ul>
  </div>
</div>  
</div>

etc.. etc..

2 Answers 2

3

You are creating everything inside your inner loop, so for each link you are creating a new item, title, etc.

Also the links.Category.results is an array, whilst you check it as so: links.Category.results == category. To check whether the Category.results contains the category string, you should use indexOf() (or includes(), but it has worse browser support).

Here's a fixed snippet:

var links = [{
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com"
    },
    "Id": 01,
    "Title": "Link 01 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 01
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 02,
    "Title": "Link 02 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 02
  },
  {

    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 03,
    "Title": "Link 01 - test category 02",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 209
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 210,
    "Title": "Link 02 - test category 02",
    "Link": "https://www.somerandomdomain.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 210
  }
]

//category arr
var categoryArr = [
  "Test Category 01",
  "Test Category 02",
  "Test Category 03"
]

var categoryTitle;
var menu = $("#output2");

$.each(categoryArr, function(catIndex, category) {
  // DOM ELEMENTS
  var $item = $('<div>').addClass('navContainer');
  var $title = $('<div>').addClass('title').appendTo($item);
  var $links = $('<ul>').appendTo(
    $('<div>').addClass('links').appendTo($item)
  );

  // CATEGORY TITLE
  $title.text(category);

  $.each(links, function(linkIndex, link) {
    var $link = $('<a>');

    if (link.Category.results.indexOf(category) != -1) {
      // ADD LINKS
      $link.attr('href', link.Link)
        .text(link.Title)
        .appendTo($('<li>').appendTo($links));
    }

  }) // end glinks

  // DISPLAY TO CONTAINER
  $item.appendTo(menu);
}) // end categoryArr
.navContainer {
  border: 1px solid grey;
  margin: 10px;
  padding: 5px;
}

.links ul li {
  list-style-type: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
  Result should look like this below
</h5>
<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
    <ul>
      <li><a href="#">http://www.google.com</a></li>
      <li><a href="#">http://www.google.com</a></li>
      <li><a href="#">http://www.google.com</a></li>
    </ul>
  </div>
</div>

<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
    <ul>
      <li><a href="#">http://www.google.com</a></li>
      <li><a href="#">http://www.google.com</a></li>
      <li><a href="#">http://www.google.com</a></li>
    </ul>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

2

Assign the links first and then do the UI stuff.

var links = [
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com"
    },
    "Id": 01,
    "Title": "Link 01 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 01
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 02,
    "Title": "Link 02 - test category 01",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 01"
      ]
    },
    "Image": null,
    "ID": 02
  },
  {

    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 03,
    "Title": "Link 01 - test category 02",
    "Link": "https://www.google.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 209
  },
  {
    "__metadata": {
      "id": "",
      "uri": "http://www.whatever.com",
      "etag": "",
      "type": ""
    },
    "Id": 210,
    "Title": "Link 02 - test category 02",
    "Link": "https://www.somerandomdomain.com",
    "Category": {
      "__metadata": {
        "type": ""
      },
      "results": [
        "Test Category 02"
      ]
    },
    "Image": null,
    "ID": 210
  }
]

//category arr
var categoryArr = [
  "Test Category 01",
  "Test Category 02",
  "Test Category 03"
]





var categories = categoryArr.map(function(label){
	var category = {}
	category.label = label
	category.links = []
	for(var i in links){
		if(links[i].Category.results.indexOf(label)!=-1)
			category.links.push(links[i])
	}
	return category
})


var menu = $("#output2");
$.each(categories, function (catIndex, category) {

	var item = $('<div>').addClass('navContainer'),
		title = $('<h4>'),
		linklist = $('<ul>')

	title.text(category.label)

	$.each(category.links, function(linkIndex, link) {

		var li = $('<li>')

		// ADD LINK
		$('<a>').attr('href',link.Link)
		.text(link.Title)
		.appendTo(li);

		li.appendTo(linklist)
	
	})

	// ADD EVERYTHING
	item.append(title,linklist);

	// DISPLAY TO CONTAINER
	item.appendTo(menu);
}) 
.navContainer {
  border: 1px solid grey;
  margin: 10px;
  padding:5px;
}
.links ul li { 
  list-style-type:none;
}
a{
  display: block;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
 Result should look like this below
</h5>
<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
  <ul>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  </ul>
  </div>
</div>  
</div>

<div class="navContainer">
  <div class="title">Category title</div>
  <div class="links">
  <ul>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  <li><a href="#">http://www.google.com</a></li>
  </ul>
  </div>
</div>  
</div>

3 Comments

Just curious, as I have not used this before, but what does map work to accomplish? Is it to simply bind or associate what links have categories already?
You have some invalid HTML in your output after building the menu. <a> links are not wrapped by <li> tags and are appended directly to the <ul>.
@VanCoon map creates a new array and fills it with each return value of the function, which is called for every entry in the array. it's a neat way of doing a for loop with push. @Krypt1 Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.