ng-repeat ng-click showing only last value from an array - javascript

I am trying to show the details of each of my values from my data in a pop up window however, only last value from an array is shown three times instead of three different values.
This is my html:
<div ng-repeat="value in all | filter: (!!locationFilter || undefined) && {type: locationFilter} | filter: priceFilter | filter: datesFilter | orderBy:sortProp">
<ul>
<li><img src="app/images/{{value.image}}.jpg" alt="Smiley face" height="100" width="240"></li>
<li><strong>{{value.id}}</strong></li>
<li><strong>{{value.address}}</strong></li>
<li>city: {{value.city}}</li>
<li>postcode: {{value.postcode}}</li>
<li>price: £{{value.price}}</li>
<li>num_of_beds: {{value.num_of_beds}}</li>
<li>{{value.type}}</li>
<li>{{value.minutes}}</li>
<li>{{value.added}}</li>
</ul>
<div ng-click="togglePopup(value)">
view details
<div class="modal-outer" ng-if="showPopup">
<div class="modal-container">
{{selectedValue.address}}
<div ng-repeat="subValue in value.details track by $index">
<ul>
<li>{{subValue.desc}}</li>
<li>{{subValue.info}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
and the javascript function:
$scope.showPopup = false;
$scope.selectedValue = {};
$scope.togglePopup = function(value) {
$scope.showPopup = !$scope.showPopup;
if (value)
$scope.selectedValue = value;
};
My data:
"allData": {
"patientsData": {
"patients": [{
"id": 1,
"image": "amsterdam",
"address": "17 Peregrine House",
"city": "London",
"postcode": "SW11 2NL",
"price": "150.000",
"num_of_beds": 1,
"type": "terraced",
"minutes": 20,
"added": "Jan 6 2017",
"details": [{
"desc": "Beautiful terraced house looking like houses in Amsterdam",
"info": "dcjkbc"
}]
}, {
"id": 2,
"image": "dutch",
"address": "22 Portland House",
"city": "London",
"postcode": "SW12 2SE",
"price": "800.000",
"num_of_beds": 3,
"type": "detached",
"minutes": 10,
"added": "Dec 28 2016",
"details": [{
"desc": "Dutch house in the countryside",
"info": "dcjkbc"
}]
}, {
"id": 3,
"image": "evy",
"address": "2 Holland Road",
"city": "London",
"postcode": "SW10 2RE",
"price": "950.000",
"num_of_beds": 4,
"type": "terraced",
"minutes": 5,
"added": "Jan 5 2017",
"details": [{
"desc": "Newly decorated house",
"info": "dcjkbc"
}]
}]
}
}
when I click view details ng-click="togglePopup(value) it shows the popup but only displaying the last value from subarray called details from my json so it would only show Newly decorated house and dcjkbc for all houses so it would be displayed three times. I would appreciate any help.

According to the documentation it is better practice to track by an objects id when it is available anyway:
If you are working with objects that have a unique identifier property, you should track by this identifier instead of the object instance. Should you reload your data later, ngRepeat will not have to rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones. For large collections, this significantly improves rendering performance. If you don't have a unique identifier, track by $index can also provide a performance boost.
Since you have an id value you should track by value.id instead:
<div ng-repeat="subValue in value.details track by value.id">
And here is a link to their documentation:
https://docs.angularjs.org/api/ng/directive/ngRepeat
As far as your error, your code works totally fine. Here is a link to a working codepen:
http://codepen.io/egerrard/pen/egvOaX
Your problem is in some other code that isn't shared here.

Try changing this line:
<div ng-repeat="subValue in value.details track by $index">
to
<div ng-repeat="subValue in all[$index].details track by $index">
I suspect value is ending by being bound to the last element of your ng-repeat. This way you should be for sure be selecting the proper value element from your list.
Attempt 2:
This is a little more of a re-write type answer. Could you update the pop-up so that it is not inside the ng-repeat?
<div class="modal-outer" ng-if="showPopup">
<div class="modal-container">
{{selectedValue.address}}
<div ng-repeat="subValue in value.details track by $index">
<ul>
<li>{{selectedValue.details.desc}}</li>
<li>{{selectedValue.details.info}}</li>
</ul>
</div>
</div>
</div>

Related

How to show a specific object in object array (Angular 5, TypeScript)

I have a data provider in Angular 5.
export class DataProvider {
location: any;
private locations: any[] = [
{
"name": "restaurant",
"location": "downtown",
"category": "restaurant",
"id": "1"
},
{
"name": "law firm",
"location": "center city",
"category": "office",
"id": "2"
},
{
"name": "public library",
"location": "suburb",
"category": "library",
"id": "3"
} ]
and here's my HTML file.
<div *ngFor="let location of locations">
<h1></h1>
<h2></h2>
</div>
In this scenario, how can I load a specific object (item) in data array with certain attributes?
For instance, If I want to load an object with "category" :"restaurant", what should I do on my HTML file? so the two others should not show up. I just want to load one out of three by using this specific attribute.
Thanks.
You need to access the attribute. You can use the following example
<div *ngFor="let location of locations">
<h1>{{location.name}}</h1>
<h2>{{location.category}}</h2>
</div>
EDIT
To filter depending on a category:
locationsFiltered = this.locations.filter(location =>location.category=="restaurant");
Now to make this example practical I will create a method to do it
filter(category : string) : any[] {
return this.locations.filter(location =>location.category==category);
}
then in html
<div *ngFor="let location of locationsFiltered">
<h1>{{location.name}}</h1>
<h2>{{location.category}}</h2>
</div>

Query in looping through JSON data set in getting front-end output

I am using this JSON data and I am suppoose to get the output as the first line will contain "EPL-2015". The second as "Match Day 1". The third line as "Date" and the fourth line as "Team1 VS Team2". But I am getting only correct output in line 1 and I am not getting rest of the outputs. Please help me in getting the rest.I think I am doing wrong in looping through the data of JSON.
var myApp = angular.module('futsalApp', []);
myApp.controller('futsalController', function($scope) {
$scope.fixtures =
{
"name": "EPL-2015",
"rounds":
[
{
"name": "Match Day 1",
"matches":
[
{
"date": "2015-08-08",
"team1":
{
"key": "manutd",
"name": "Manchester United",
"code": "MUN"
},
"team2":
{
"key": "tottenham",
"name": "Tottenham Hotspur",
"code": "TOT"
},
"score1": 1,
"score2": 0
},
{
"date": "2015-08-08",
"team1":
{
"key": "bournemouth",
"name": "Bournemouth",
"code": "BOU"
},
"team2":
{
"key": "astonvilla",
"name": "Aston Villa",
"code": "AVL"
},
"score1": 0,
"score2": 1
}
]
}
]
}
})
.
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="fixtures-first" ng-repeat="fix in fixtures">
<a>
<h2 class="match-title"> {{fixtures.name}} </h2>
<p class="match-day"> {{fixtures.rounds.name}} </p>
<p class="match-day"> {{fixtures.rounds.matches.date}} </p>
</a>
</div>
</div>
</div>
Here are the problems. In this line:
<div class="fixtures-first" ng-repeat="fix in fixtures">
...you're not setting your loop correctly. fixtures is a Javascript object, not an array, so you're not looping the way you want. You also never use fix for anything, so I think you've misunderstood how to use ng-repeat.
What you probably mean to do is repeat over your matches array, which is an actual array. Below, note that fixtures.rounds[0] is the first element of your rounds array.
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="fixtures-first" ng-repeat="match in fixtures.rounds[0].matches">
<a>
<h2 class="match-title"> {{fixtures.name}} </h2>
<p class="round-name"> {{fixtures.round[0].name}} </p>
<p class="match-day"> {{match.date}} </p>
</a>
</div>
</div>
</div>

angularjs - ng repeat with json

how can i use ng-repeat for below json
$scope.prlists = {
"1": [{
"id": "1",
"name": "One",
"qty": 2,
"amount": "1.00",
"cat": "1.00"
}],
"3": [{
"id": "3",
"name": "backit",
"qty": 3,
"amount": "2.00",
"cat": "2.00"
}]
}
<div ng-repeat="pro in prlists">
name : pro.name
</div>
can not able to get the name due to inner array. How to solve
ngRepeat can iterate over object properties. So, you can do something like
<div ng-repeat="(key, pro) in prlists">
name: {{pro[0].name}}
</div>
See the documentation at: https://docs.angularjs.org/api/ng/directive/ngRepeat
Note that this will not guarantee the order in Angular version >= 1.4, since it will depend on the browser's ordering. You might be able to sort it using the orderBy filter
<div ng-repeat="(key, pro) in prlists | orderBy:key">
name: {{pro[0].name}}
</div>
See: https://docs.angularjs.org/api/ng/filter/orderBy
If the inner arrays are not just a single element, you may have to nest a second ngRepeat inside the first div.
As I have already commented:
try pro[0].name
Reason:
In you code, for every iteration, $data(pro) will have
[{
"id": "1",
"name": "One",
"qty": 2,
"amount": "1.00",
"cat": "1.00"
}]
Now as you see, this is not an object, so you have to go to its first and only child. Also you are missing {{}}. name : pro.name this will print pro.name as text and not parse it.
Working demo.

Angularjs Filter array using property inside other object

I have the following Json File...
ill Show u only 1 object...
i have 154 with the same structure i want filter the name... when in art_type.name = '--Something...--'
{
"1": {
"name": "Miami City Ballet",
"created": "2011-04-24 00:39:28",
"modified": "2015-09-02 09:30:49",
"author": [],
"slug": "miami-city-ballet",
"address": "2200 Liberty Ave.",
"city": "Miami Beach",
"state": "Fl.",
"zipcode": "33139",
"phone_number": "Box Office: 305 929 7010",
"email_address": "eparkinson#miamicityballet.org",
"web_address": "http://www.miamicityballet.org",
"twitter_address": "https://twitter.com/MiamiCityBallet",
"facebook_address": "https://www.facebook.com/miamicityballetschool",
"instagram_address": "",
"gallery_hours": "<div><span style=\"line-height: 1.4em;\">order </span><span style=\"line-height: 1.4em;\">by phone 1 877 929 710</span></div>\n<div>or in person</div>\n<div><b>Box Office Hours:</b></div>\n<div>Mon - Fri: 10 - 5</div>\n<div><b>Tickets start at $25</b></div>\n<div>Grand Opening:</div>\n<div><b>Friday, October 23, 8 pm</b></div>\n<div><b>Arsht Center</b></div>",
"gallery_id": "46",
"additional_details": "October 23 - November 15\n<h3>Program One:</h3>\n<div>Swan Lake – Balanchine/Tchaikovsky</div>\n<div>Viscera – Scarlett/Liebermann</div>\n<div>Fancy Free – Robbins/Bernstein</div>",
"gallery_additional_info": "Swan Lake is the most famous of all ballets, its name practically synonymous with the art form. Miami City Ballet is excited to be bringing back to our audiences the glorious version of Acts Two and Four – the “white acts” – that George Balanchine created in 1951 for Maria Tallchief and New York City Ballet. More than a tragic romance, it is a timeless meditation on the universal experience of love and loss, set to Tchaikovsky’s most evocative score.",
"critics_choice": "0",
"circuit": {
"6": {
"name": "Art Is Everywhere",
"created": "2011-04-24 00:33:19",
"modified": "2011-04-24 00:33:19",
"author": false,
"slug": "art-is-everywhere",
"id": 6
}
},
"art_type": {
"1": {
"name": "Performing Arts",
"created": "2011-04-24 00:29:55",
"modified": "2011-04-24 00:29:55",
"author": false,
"slug": "performing-arts",
"id": 1
}
},
"monthly_update": {
"ID": "273",
"post_author": "1",
"post_date": "2011-04-14 16:45:58",
"post_date_gmt": "2011-04-14 21:45:58",
"post_content": "April 1 - 3\r\nKravis Center for the Performing Arts\r\n\r\nApril 29 - May 1\r\nBroward Center for the Performing Arts\r\n<strong> Program IV - Romeo and Juliet</strong>\r\nThe Company Premiere of John Cranko’s version\r\n<em>The New York Times raves, “arguably the best dance treatment of Prokofiev’s celebrated score.â€</em>\r\n<table border=\"0\" cellspacing=\"2\" cellpadding=\"1\" width=\"350\" align=\"center\">\r\n<tbody>\r\n<tr>\r\n<td align=\"center\" valign=\"top\">\r\n<div><img src=\"http://www.artcircuits.com/newsletters/images/Jennifer-Kronenberg-and-Carlos-Guerra-11.jpg\" alt=\"image\" width=\"100\" height=\"74\" align=\"top\" /></div></td>\r\n<td height=\"100\" align=\"center\" valign=\"top\">\r\n<div><img src=\"http://www.artcircuits.com/newsletters/images/2Jennifer-Kronenberg-and-Carlos-Guerra-11.jpg\" alt=\"image\" width=\"98\" height=\"127\" align=\"top\" /></div></td>\r\n<td align=\"center\" valign=\"top\">\r\n<div><img src=\"http://www.artcircuits.com/newsletters/images/Carlos-11.jpg\" alt=\"image\" width=\"100\" height=\"99\" /></div></td>\r\n</tr>\r\n<tr>\r\n<td width=\"100\" align=\"center\" valign=\"top\">\r\n<div>Jennifer Kronenberg and Carlos Guerra in Romeo and Juliet. Photo © 2009 Lois Greenfield.</div></td>\r\n<td width=\"100\" height=\"0\" align=\"center\" valign=\"top\">\r\n<div>Jennifer Kronenberg and Carlos Guerra in Romeo and Juliet. Photo © 2009 Lois Greenfield.</div></td>\r\n<td width=\"100\" height=\"0\" align=\"left\" valign=\"top\">\r\n<div>Carlos Guerra in Romeo and Juliet. Photo © 2009 Lois Greenfield.</div></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nMore www.miamicityballet.org",
"post_title": "Miami City Ballet - April 2011",
"post_excerpt": "",
"post_status": "publish",
"comment_status": "open",
"ping_status": "open",
"post_password": "",
"post_name": "miami-city-ballet-april-2011",
"to_ping": "",
"pinged": "",
"post_modified": "2011-04-14 16:54:57",
"post_modified_gmt": "2011-04-14 21:54:57",
"post_content_filtered": "",
"post_parent": "0",
"guid": "http://artcircuits..com/?p=273",
"menu_order": "505",
"post_type": "post",
"post_mime_type": "",
"comment_count": "0",
"pod_item_id": "273"
},
"thumbnail": false,
"caption": "<!-- [if gte mso 9]><xml>\n<o:DocumentProperties>\n<o:Template>Normal.dotm</o:Template>\n<o:Revision>0</o:Revision>\n<o:TotalTime>0</o:TotalTime>\n<o:Pages>1</o:Pages>\n<o:Words>33</o:Words>\n<o:Characters>191</o:Characters>\n<o:Company>lpa2790</o:Company>\n<o:Lines>1</o:Lines>\n<o:Paragraphs>1</o:Paragraphs>\n<o:CharactersWithSpaces>234</o:CharactersWithSpaces>\n<o:Version>12.0</o:Version>\n</o:DocumentProperties>\n<o:OfficeDocumentSettings>\n<o:AllowPNG></o:AllowPNG>\n</o:OfficeDocumentSettings>\n</xml><![endif]--><!-- [if gte mso 9]><xml>\n<w:WordDocument>\n<w:Zoom>0</w:Zoom>\n<w:TrackMoves>false</w:TrackMoves>\n<w:TrackFormatting></w:TrackFormatting>\n<w:PunctuationKerning></w:PunctuationKerning>\n<w:DrawingGridHorizontalSpacing>18 pt</w:DrawingGridHorizontalSpacing>\n<w:DrawingGridVerticalSpacing>18 pt</w:DrawingGridVerticalSpacing>\n<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>\n<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>\n<w:ValidateAgainstSchemas></w:ValidateAgainstSchemas>\n<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>\n<w:IgnoreMixedContent>false</w:IgnoreMixedContent>\n<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>\n<w:Compatibility>\n<w:BreakWrappedTables></w:BreakWrappedTables>\n<w:DontGrowAutofit></w:DontGrowAutofit>\n<w:DontAutofitConstrainedTables></w:DontAutofitConstrainedTables>\n<w:DontVertAlignInTxbx></w:DontVertAlignInTxbx>\n</w:Compatibility>\n</w:WordDocument>\n</xml><![endif]--><!-- [if gte mso 9]><xml>\n<w:LatentStyles DefLockedState=\"false\" LatentStyleCount=\"276\">\n</w:LatentStyles>\n</xml><![endif]-->\n\n<!-- [if gte mso 10]>\n\n<style>\n /* Style Definitions */\ntable.MsoNormalTable\n{mso-style-name:\"Table Normal\";\nmso-tstyle-rowband-size:0;\nmso-tstyle-colband-size:0;\nmso-style-noshow:yes;\nmso-style-parent:\"\";\nmso-padding-alt:0in 5.4pt 0in 5.4pt;\nmso-para-margin:0in;\nmso-para-margin-bottom:.0001pt;\nmso-pagination:widow-orphan;\nfont-size:12.0pt;\nfont-family:\"Times New Roman\";\nmso-ascii-font-family:Cambria;\nmso-ascii-theme-font:minor-latin;\nmso-fareast-font-family:\"Times New Roman\";\nmso-fareast-theme-font:minor-fareast;\nmso-hansi-font-family:Cambria;\nmso-hansi-theme-font:minor-latin;}\n</style><![endif]-->\n\n<!--StartFragment-->\n<h3></h3>\n<h3></h3>\n<!--EndFragment-->",
"id": 1
},
this is my full json http://artcircuits.com/wp-json/pods/art_places.... use some json online viewer
<ion-view view-title="WYNWOOD ARTS DISTRICT">
<ion-content class="padding" style="background-color: #E5E5E4; color:#8B7447; top:54px">
<ul class="list" ng-repeat="equis in arreglo">
<a href="#" class="item " >{{equis.name}}</a>
</ul>
well i have all my object.. in one $scope.variable...
i want to do the next...
FILTER by art_type array property name or index....
Please i need a simple solution... maybe do the filter in controller... or something...
One way to do this is in two steps:
"flatten" the object into an array that's easier to filter. (in my example I'm using lodash to do this)
use the regular angular filter in the markup.
Here's the example
And here's inline code:
HTML:
<div ng-repeat="item in arr | filter: {art_type:filterByArtType}">
{{item.name}}
</div>
JavaScript:
angular.module('myApp').controller('myCtrl', function($scope) {
$scope.filterByArtType = 1;
$scope.obj = {
"1": {
"id": 1,
"name": "Miami City Ballet",
...
"art_type": {
"1": {
"name": "Performing Arts"
}
}
...
},
...
};
$scope.arr = _.chain($scope.obj)
.values()
.map( function(n) {
n.art_type = _.keys(n.art_type)[0];
return n;
}).value();
});
UPDATE: Now making the flattened array's "art_type" value be the "id" instead of the name.
What you want is the angular built-in filter filter. It can be used in an ng-repeat to restrict which elements of an array are used for generating elements in the DOM, without modifying the source array.
Official angular documentation for filter filter.

Displaying JSON with ng repeat

I have a JSON data in the format
[
{
"_1": {
"id": 4,
"cost": 45.0,
"measure": 4,
"NoOfUnits": 677,
"hours": null
},
"_2": {
"id": 1,
"name": "Truck",
"description": "Test"
}
},
{
"_1": {
"id": 1,
"cost": 1120.0,
"measure": 1,
"NoOfUnits": 500,
"hours": null
},
"_2": {
"id": 7,
"name": "PC300",
"description": null
}
},
]
I'm not able to display the data that I have store in a $scope variable say
$scope.result
This is my ng repeat functionality
<div ng-repeat="data in result">{{data.name}}{{data.description}}</div>
your $scope.result is contains 2 objects, with in one object u have set of object properties like _1,_2 , and then these properties are again objects like
"_1": {
"id": 4,
"cost": 45.0,
"measure": 4,
"NoOfUnits": 677,
"hours": null
}
, then u have the properties u need to print.
<ul>
<li ng-repeat="x in result"> // repeats objects
<ul ng-repeat="obj in x"> // repeat object properties '_1',"_2" , these are again objects
{{obj.name}}{{obj.description}}
<ul>
</li>
</ul>
With your data structure... You cannot access name and description directly from first ng-repeat.
Even if you have nested ng-repeat you are not guaranteed with name and description. You need to flatten the object after first ng-repeat and then you can access all the properties. Assuming that _1, _2 object properties are related.
Two loops are required---
<div ng-repeat="data in result">
<div ng-repeat="obj in data">
{{obj.cost}}{{obj.name}}
</div>
</div>
Demo: http://jsfiddle.net/HB7LU/8254/

Categories