Hack-R Hack-R - 2 months ago 8
Javascript Question

Display list of object's child arrays with 1 bullet per index using ng-repeat

I have an object (

searchedMenu
) containing 3 arrays of equal lengths (
name
,
short_name
, and
description
).

for(var i=0;i<description.length;i++){
searchedMenu.name[i] = description[i].name;
searchedMenu.short_name[i] = description[i].short_name;
searchedMenu.description[i] = description[i].description;
}
menu.searchedMenu = searchedMenu;


I want to display each
name
,
short_name
, and
description
as an unordered list item like this:


  • name1, short_name1, description1

  • name2, short_name2, description2



I'm struggling to do this. I've declared my controller in the relevant
div
as

<div class="container" ng-controller = "NarrowItDownController as narrow">


If I do this:

<ul>
<li ng-repeat="item in narrow.searchedMenu"> {{item}}</li>
</ul>


I get 3 bullet points containing all elements of each array like this:


  • name1, name2,...

  • short_name1, short_name2, ...

  • description1, description2, ...



If I do this:

<li ng-repeat="item in narrow.searchedMenu"> {{item.name}}, {{item.short_name}}, {{item.description}}</li>


I get:


  • , ,

  • , ,

  • , ,



As an experiment I also tried this:

<li ng-repeat="item in narrow.searchedMenu.name"> {{item}}</li>


and it gave me nothing in the browser with a console error of:


Error: [ngRepeat:dupes]
http://errors.angularjs.org/1.5.8/ngRepeat/dupes?p0=item%20in%20narrow.searchedMenu.name&p1=string%3AOrange%20Chicken&p2=Orange%20Chicken


The
console.log("Searched menu: ", menu.searchedMenu);
is:

Searched menu: Object {name: Array[219], short_name: Array[219], description: Array[219]}


The full controller code is (this is a dirty work in progress):

NarrowItDownController.$inject = ['MenuSearchService'];
function NarrowItDownController(MenuSearchService) {
var menu = this;

var promise = MenuSearchService.getMatchedMenuItems();
var item_name = ["",""];
var description;

var searchValue = "ton";
function containsFilter(value) {
return value.indexOf(searchValue) !== -1;
}

promise.then(function (response) {
menu.results = response.data;
menu.results = menu.results.menu_items;

description = response.data;
description = description.menu_items;
console.log(description);

var searchedMenu = {};
searchedMenu.name = [];
searchedMenu.short_name = [];
searchedMenu.description = [];

for(var i=0;i<description.length;i++){
searchedMenu.name[i] = description[i].name;
searchedMenu.short_name[i] = description[i].short_name;
searchedMenu.description[i] = description[i].description;
}

console.log(searchedMenu);
menu.searchedMenu = searchedMenu;//description.filter(containsFilter);
console.log("Searched menu: ", menu.searchedMenu);

})
.catch(function (error) {
console.log("Something went terribly wrong.");
});

menu.logMenuItems = function (searchTerm) {
var promise = MenuSearchService.getMatchedMenuItems(searchTerm);

promise.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
})
};

}


Note that I hard coded the search term in the example above because it's a work in progress.

Answer

Try this:

<ul>
  <li ng-repeat="item in narrow.searchedMenu.name track by $index"> {{ item }}, {{ narrow.searchedMenu.short_name[$index] }}, {{ narrow.searchedMenu.description[$index] }}</li>
</ul>

The searchedMenu object contains three arrays, therefore you can loop through one of the arrays and in each step of the loop, extract the elements from the other arrays with the $index.

AngularJS does not allow duplicates in a ng-repeat directive therefore you must add track by $index to your repeater