I want to display the json in a certain format with ng-repeat, but have had no success.
This is the structure:
<div ng-repeat="book in books">
{{book}}
<div ng-repeat="name in book.name" >{{name}} </div>
</div>
THis is the structure how I want it to display on the page:
Genre:
Sci-fic
Bookname1
Bookname2
Non sci-fic
Bookname3
Bookname4
This is the json sample:
[{"Genre":Sci-fic,"Name":"Bookname1"},
{"Genre":Sci-fic,"Name":"Bookname2"},
{"Genre":Non sci-fic,"Name":"Bookname3"},
{"Genre":Non sci-fic,"Name":"Bookname4"}]
http://jsfiddle.net/HB7LU/4053/
Should/Need to fix/restructure your JSON
$scope.books = [
{
"genre": "Sci-fic",
"titles" : ['Bookname1', 'Bookname2']
},
{
"genre": "Non sci-fic",
"titles" : ['Bookname3', 'Bookname4']
},
];
<div ng-repeat="book in books">
{{book.genre}}
<div ng-repeat="title in book.titles" >{{title}}</div>
</div>
Wouldn't it be easier if you format the json object that you receive like this?:
[{
"name": "Sci-Fic",
"names":["book 1","book 2"]
},
{
"name": "Another Genre",
"names":["book 1","book 2"]
}
]
Why don't u use ul and li? just another approach.
<ul>
<li ng-repeat="genre in books">
{{genre.name}}
<ul>
<li ng-repeat="name in genre.names">{{name}}</li>
</ul>
</li>
</ul>
Hope it helps :D
---Edit---
Sry, didn't see #Christopher Marshall answer while i was writing, its the same thing.
If the data MUST be in that format you can do this:
<div ng-app="app">
<div ng-controller="ParentCtrl">
<div data-ng-repeat="genre in data | orderBy:'Genre'">
<span data-ng-if="(data | orderBy:'Genre')[$index - 1].Genre != genre.Genre">
{{ genre.Genre }}
</span>
<div style="padding-left: 30px;">{{ genre.Name }}</div>
</div>
</div>
</div>
Here's a jsFiddle of it: http://jsfiddle.net/wgLnH/
Related
I have a complex object as shown below:
$scope.document =
{
"GENERAL_FIELDS": {
"Source_Type": "custom",
"Annotations": [
"216/content/Factiva_CM_001/Proteins",
"216/content/Factiva_CM_001/Fact"
],
"Content": [
" Baculovirus; Budded virus; Ultrastructure; Cryo-EM;"
],
"Title": [
"Budded baculovirus particle structure revisited"
]
},
"stn": {
"Document_Type": [
"Journal",
"Article"
]
}
}
I want to display all the fields present in "GENERAL_FIELDS" and "stn". Fields' value can either be string or array of strings. If it is array, I further want to ng-repeat on it and display the content. Following is my html:
<div id="titsec" class="comdocdet" ng-repeat="(category, group) in document">
<div ng-repeat="(key, value) in group">
<div class="pTitle">
{{key}}
</div>
<div class="contdesc">
<div ng-if="Array.isArray(value)">
<div ng-repeat="v in value">
{{v}}
</div>
</div>
<div ng-if="!Array.isArray(value)">
{{value}}
</div>
</div>
</div>
</div>
But ng-if="Array.isArray(value)" is never true and array fields are being displayed in object form: ["Journal","Article"]. What am I missing ?
Or add this in your controller and leave rest like it is.
$scope.isArray = angular.isArray;
html would be like this :
<div ng-if="isArray(value)">
<div ng-repeat="v in value">
{{v}}
</div>
</div>
<div ng-if="!isArray(value)">
{{value}}
</div>
Instead of accessing a method on the Array object directly in the template, you should do in your controller. So for example:
<div ng-if="vm.isValueAnArray(value)">
// Some html
</div>
Your controller:
function isValueAnArray(val) {
return Array.isArray(val);
}
I haven't tested it, but logic should be in the controller, not in the template.
This is an issue of Scoping
The scope of the template is relative to $scope in the controller, so when it looks for Array, it will look for that in the controller scope (e.g. $scope.Array).
One option is to use ng-if="window.Array.isArray(value)". See the working example below.
Another option is to set $scope.Array = Array.prototype in the controller. That way there is no need to reference window before calling Array.isArray().
Another option is to create an alias for Array.isArray() in the controller scope:
$scope.isValueAnArray = Array.isArray;
Then call that function to determine if the value is an array.
angular.module('ang', [])
.controller('cont', function($scope) {
//use this to avoid referencing window in the template
//$scope.Array = Array.prototype;
$scope.document = {
"GENERAL_FIELDS": {
"Source_Type": "custom",
"Annotations": [
"216/content/Factiva_CM_001/Proteins",
"216/content/Factiva_CM_001/Fact"
],
"Content": [
" Baculovirus; Budded virus; Ultrastructure; Cryo-EM;"
],
"Title": [
"Budded baculovirus particle structure revisited"
]
},
"stn": {
"Document_Type": [
"Journal",
"Article"
]
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ang" ng-controller="cont">
<div id="titsec" class="comdocdet" ng-repeat="(category, group) in document">
<div ng-repeat="(key, value) in group">
<div class="pTitle">
{{key}}
</div>
<div class="contdesc">
<div ng-if="window.Array.isArray(value)">
<div ng-repeat="v in value">
{{v}}
</div>
</div>
<div ng-if="!window.Array.isArray(value)">
{{value}}
</div>
</div>
</div>
</div>
</div>
I have a json file named (for now) 0.json. I want to display certain arrays within the json object as individual values (maybe display them as badges).
here is my json:
[
{
"id": "Chinwe Chukuwogu Roy WordPress Biography Website",
"name": "Chinwe Roy Biography Website",
"practices": ["UX", "HTML WireFraming", "Front-End Development", "Custom WordPress Theming"],
"technology": ["WordPress", "HTML", "CSS", "JQuery", "TweenMax", "Inkscape", "Photoshop"],
"time": "6 Weeks",
"description": "A biography website celebrating the work of world reknowned Artist, Chinwe Chukwogu Roy",
"images": "../assets/img/ux.svg",
"header": "../assets/img/wordpress-project.svg",
"behance": "https://www.behance.net/gallery/33173663/UI-Design-A-Website-Biography-Project"
}
]
I call the json like this within my controller:
$http.get('app/resources/v1/projects/' + $routeParams.id + '.json').success(function (details) {
$scope.details = details;
});
HTML:
<div class="row" ng-controller="ProjectCtrl">
<ng-header class="header-directive">{{ detail.header }}</ng-header>
<div class="container">
<div class="row">
<div class="col-md-12 work-parent" ng-repeat="detail in details">
<div class="work-child">
<h1>{{ detail.id }}</h1>
<br>
<p>{{ detail.description }}</p>
<small><strong>technologies:</strong> {{ detail.technology }}</small>
<small><strong>design practice:</strong> {{ detail.practices }}</small>
<small><strong>turnaround:</strong> {{ detail.time }}</small>
<ul class="social-icons">
<li class="behance">behance</li>
</ul>
</div>
</div>
</div>
</div>
</div>
The issue I am having is that I am unable to show e.g practices as individual values. I just get an complete array in the view when I bind detail.practices with an ng-repeat.
How would I manage this in my controller?
Just nest another ng-repeat inside your main one, so along the lines of:
<small ng-repeat="practice in detail.practices"><strong>design practice:</strong> {{ practice }}</small>
Or however else you want them to appear.
instead of this :
<small><strong>design practice:</strong> {{ detail.practices }}</small>
you can write this , so that you get each value of the array
<small><strong>design practice:</strong>
<ul>
<li ng-repeat="practice in detail.practices">{{ practice }}</li>
</u>
</small>
Hope that helps, good luck.
Try to use indexes
<div class="col-md-12 work-parent" ng-repeat="{index, detail} in details">
<div class="work-child">
<h1>{{ detail.id }}</h1>
<br>
<p>{{ detail.description }}</p>
<small><strong>technologies:</strong> {{ detail.technology }}</small>
<small><strong>design practice:</strong> {{ detail.practices }}
<div ng-if="detail.practices.length > 0">
<b ng-repeat="practice in details[index].practices">{{ practice }}</b>
</div>
</small>
<small><strong>turnaround:</strong> {{ detail.time }}</small>
<ul class="social-icons">
<li class="behance">behance</li>
</ul>
</div>
</div>
In my angular js controller, I have a json array that contains continents and inside the continents contain an array of countries
//CONTROLLER
app.controller('CountryController', function(){
this.continents =
[
{
name:'Africa',
countries:
[
{ name: 'Algeria', code:'DZ', operators:'3'},
{ name: 'Angola', code:'AO', operators:'1'},
{ name: 'Benin', code:'BJ', operators:'2'},
{ name: 'Burkina Faso', code:'BF', operators:'1'}
],
},
{
name:'AsiaPacific',
countries:
[
{ name: 'Afghanistan', code:'AF', operators:'4'},
{ name: 'Bahrain', code:'BH', operators:'2'}
],
}
];
});
In my view i want to display the countries in tabbed elements arranged by continents i.e I have tabs to hold the countries in each continent. e.g i have a tab for Africa and inside this tab i want to display the countries in the Africa object.
I have tried using the 'filter' to display only countries in a particular continent in each tab but it is not working neither does anything show up. On inspecting the element the code seems to be commented. This is the first task I am trying to accomplish using Angular-js so I am still learning the ropes.
This is what my view looks like
<div ng-app="countriessupported" class="container container_with_height">
<div ng-controller="CountryController as countryCtrl" id="myTabContent" class="tab-content hidden-xs">
<div class="tab-pane fade active in" id="africa">
<div class="col-md-12 countries_col-12" ng-repeat="continent in countryCtrl.continents.name | filter: 'Africa' ">
<a href="">
<div class="col-md-3 country_container" ng-repeat="country in continent.countries">
<div class="country_name">
{{ country.name }}
</div>
</div>
</a>
</div>
</div>
</div>
</div>
So the idea is to have the countries repeated in the div with class col-md-3
How can i achieve this please?
Try this html Code
<div ng-app="countriessupported" class="container container_with_height">
<div ng-controller="CountryController as countryCtrl" id="myTabContent" class="tab-content hidden-xs">
<div class="tab-pane fade active in" id="africa">
<div class="col-md-12 countries_col-12" ng-repeat="continent in countryCtrl.continents | filter: 'Africa' ">
<a href="">
<div class="col-md-3 country_container" ng-repeat="country in continent.countries">
<div class="country_name">{{ country.name }}</div>
</div>
</a>
</div>
</div>
</div>
</div>
let me know if this is helpful
Try to change you first repeater to this ng-repeat="continent in countryCtrl.continents instead of ng-repeat="continent in countryCtrl.continents.name the filter sholud be working anyway
I have a html like this :
<div class="fields-plan"data-ng-repeat="roomname in assign.roomname">
<section>
<span>Room: {{roomname}}</span>
</section>
<ul data-ng-repeat="room in assign.rooms.roomname">
<li>
{{room.room}}
</li>
<ul>
</div>
and my angular controller look like this:
var room = {"1.2":
[
{room: "1.2.1"},
{room: "1.2.2"},
{room: "1.2.3"}
],
"1.3": [
{room: "1.3.1"},
{room: "1.3.2"},
{room: "1.3.3"}
]};
var keys = Object.keys(room);
this.roomname = keys;
this.rooms = room;
In my second ng repeat, it doesn't work and how can i loop based on roomname, that output from the first ng repeat??
Your second ng-repeat needs to take the first ng-repeat value instead of directly taking the room name, so your second ng-repeat should look like this:
Code:
<div class="fields-plan"data-ng-repeat="(key, value) in assign.rooms">
<section>
<span>Room: {{key}}</span>
</section>
<ul data-ng-repeat="room in value">
<li>
{{room.room}}
</li>
<ul>
</div>
You can achieve this by slightly reformatting your Json and then using the following code:
The key is to use the value of the first ng-repeat in the second ng-repeat and not trying to reference the first collection.
html:
<div ng-controller="MyCtrl">
<div class="fields-plan" ng-repeat="room in rooms">
<section>
<span>Room: {{room.name}}</span>
</section>
<ul ng-repeat="subroom in room">
<li>
{{room.subRoom}}
</li>
<ul>
</div>
</div>
javascript:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.rooms = [ { name : "1.2",
subRoom: [
"1.2.1","1.2.2","1.2.3"],
}, { name: "1.3",
subRoom: [
"1.3.1","1.3.2","1.3.3"]}];
}
Fiddle demo: http://jsfiddle.net/0pnam0wj/
Is this you wanted?
plnkr
<div data-ng-repeat="(roomnamePrefix, roomname) in rooms">
<section>
<span>Room: {{roomnamePrefix}}</span>
</section>
<ul data-ng-repeat="room in roomname">
<li>
{{room.room}}
</li>
<ul>
</div>
I have set up a fiddle to explain my question well. I would like to display the names from the $scope.gem inside ng-repeat [only one name for each ng-repeat and don't loop all] of $scope.knobItems without extending the knobItems scope. I want this to be made possible by maintaining the exact structure of controller as it is now. I am new to angular. I just wanna know if this is possible in angular and if is a good practice.
view
<div ng-app="myapp">
<div ng-controller="Mycont">
<div ng-repeat="knobs in knobItems">
<div ng-repeat="(key, value) in knobItems.nums">{{value.knobTitle}} : {{value.knobColor}}
<div ng-bind="gem[0].name"></div>
</div>
</div>
</div>
</div>
controller
var ngMod = angular.module("myapp", []);
ngMod.controller("Mycont", function ($scope) {
$scope.knobItems = {};
$scope.knobItems.nums = [{
knobTitle: "Company Profile",
knobColor: "#f46607"
}, {
knobTitle: "Deals left This Month",
knobColor: "#ffcc00"
}, {
knobTitle: "Pricelist",
knobColor: "#f40787"
}, {
knobTitle: "Pictures",
knobColor: "#a1b80a"
}, {
knobTitle: "Videos",
knobColor: "#14b9d6"
}];
$scope.gem = [{
name: "Thomas"
}, {
name: "Sebastian"
}, {
name: "June"
}, {
name: "Yuvan"
}];
});
intended output
Easy fix: fiddle
<div ng-app="myapp">
<div ng-controller="Mycont">
<div ng-repeat="knobs in knobItems">
<div ng-repeat="(key, value) in knobItems.nums">{{value.knobTitle}} : {{value.knobColor}}
<div ng-bind="gem[$index].name"></div>
</div>
</div>
</div>
</div>
The output in you fiddle is exactly the same without the first ng-repeat: http://jsfiddle.net/2nrbrfxL/
Going by you description rather than you code:
<div ng-app="myapp">
<div ng-controller="Mycont">
<div ng-repeat="knobs in knobItems">
<div ng-repeat="(key, value) in knobs">{{value.knobTitle}} : {{value.knobColor}}
<div ng-repeat="gemItem in gem">{{gemItem.name}}</div>
</div>
</div>
</div>
</div>
http://jsfiddle.net/p2fuq2du/
<div ng-app="myapp">
<div ng-controller="Mycont">
<div ng-repeat="(key, value) in knobItems.nums">{{value.knobTitle}} : {{value.knobColor}}
<div ng-bind="gem[key].name"></div>
</div>
</div>
</div>