I am new to angular. I have a task to display json data in specific design, but I have not idea about nesting of json. Is it possible to check if the data is json or an array of json and then display the output.
Here I am trying to display data only if it is an array. But it is not working. Kindly help.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp">
<div ng-controller="readJson as rj">
<div ng-repeat="d in rj.data">
<ul>
<div ng-model="myVar" ng-init="myVar = "{{isArray(d.third)}}>
<div ng-if="myVar">
<li>{{d.third}}</li>
</div>
</ul>
</div>
</div>
</div>
</body>
<script>
(function(){
var app=angular.module('myApp',[]);
app.controller('readJson',function($scope){
$scope.isArray = angular.isArray;
this.data=[{"first":"one","second":"two","third":"three"},
{"first":"ONE","second":"two","third":"three"},
{"first":"onE","second":"two","third":
[
{"first":"1one","second":"2two","third":"3three"},
{"first":"1ONE","second":"2two","third":"3three"}
]}];
});
})();
</script>
</html>
Here you go. This example will display data only when "third" param is an array.
https://plnkr.co/edit/EX0BvcYrLPFbiN2ezlqQ
<div ng-repeat="d in data">
<ul>
<div ng-init="myVar = isArray(d.third)"></div>
<div ng-if="myVar">
<li>{{d.third}}</li>
</div>
</ul>
</div>
The problem was in ng-init="myVar = "{{isArray(d.third)}} - you need to make sure isArray(d.third) is in expression (between "") and there is no need to use {{}} syntax within ng-init directive. It will evaluate expression for you (check an example).
Related
I'm having trouble trying to figure out how to fix a bug that happens when I try to push the same string as added previously to the array. It gets stuck and will not allow the app to post another string.
How do I make sure that your repeat doesn't get stuck when there two of the same values in the array?
Bug Example Screenshot
--> Bug happens when I try to push "1"into the array again after a "1" is already posted.
HTML Code
<body>
<div data-ng-controller="appController" class="container">
<div class="row">
<form>
<label for = "status"> Status: </label>
<input data-ng-model = "input_data" type="text" id="status"/>
<button data-ng-click="add_data()"> OK </button>
<ul class = "list-group">
<li class="list-group-item" data-ng-repeat="x in array_data">
{{x}}
<button data-ng-click = "remove_data($index)">DEL</button>
</li>
</ul>
</form>
</div>
</div>
<script src="framework/js/jquery.min.js"></script>
<!-- All Bootstrap plug-ins file -->
<script src="framework/js/bootstrap.min.js"></script>
<!-- Basic AngularJS -->
<script src="framework/js/angular.min.js"></script>
<!-- Your Controller -->
<script src="framework/js/appstatpost.js"></script>
</body>
AngularJS code
var app = angular.module("myApp", []);
app.controller("appController", function ($scope) {
$scope.array_data = [];
$scope.add_data = function () {
$scope.array_data.push($scope.input_data);
};
$scope.remove_data = function (index) {
$scope.array_data.splice(index, 1);
};
});
You could use track by $index, example:
<li class="list-group-item" data-ng-repeat="x in array_data track by $index">
AngularJS tries by default to find a key in your array to index by. Normally this works well, but if you have duplicates then you have to tell AngularJS to make a new index, in this case, $index.
I need one help. I need to create extra input element using ng-repeat in angular.js. I did something but its not working. I explaining my code below.
<div>
<ul>
<li ng-repeat="r in arr">
<input type="text" ng-model="r.uname">
</li>
</ul>
</div>
<button type="button" id="btn" ng-click="create();">Add</button>
Here I need when user will click on add button the new input field will create just below the first one. My scripting side code is given below.
<script type="text/javascript">
function ContactController($scope){
$scope.arr=[{uname:null}];
$scope.create=function(){
console.log('hii');
$scope.arr.push({
uname:null
});
console.log('hi',$scope.arr);
}
}
</script>
But here i am unable to generate the new input type element. Please help me.
I don't see an error in your code. it works: http://jsfiddle.net/Lvc0u55v/9536/
$scope.arr=[{uname: null}];
$scope.create = function(){
console.log('hii');
$scope.arr.push({
uname: null
});
console.log('hi',$scope.arr);
}
Define your array like this..
$scope.arr=[{}];
$scope.create=function(){
$scope.arr.push({});
console.log('hi',$scope.arr);
}
everything else looks fine..
Please refer to this.
Use track by in order to achieve the thing you're aiming for:
<li ng-repeat="r in arr track by $index">
the first thing u are pushing the same element in the array so you want to track the in the ng-repeat
<div ng-repeat="r in arr track by $index">
<input type="text" ng-model="r.uname"> </div>
still it is not creating then try the console is coming and it is not creating
use $scope.$apply() to manually run the digest cycle
Which version of angular are you running. The code which you mentioned would not work in angular 1.3 and above. It works in 1.2 though. See this with 1.2
https://plnkr.co/edit/52ygFNbSFZQr3SdCvlDc?p=preview
<body ng-controller="ContactController">
<p>Hello {{name}}!</p>
<div>
<ul>
<li ng-repeat="r in arr">
<input type="text" ng-model="r.uname">
</li>
</ul>
</div>
<button type="button" id="btn" ng-click="create();">Add</button>
<script type="text/javascript">
function ContactController($scope){
$scope.arr=[{uname:null}];
$scope.create=function(){
console.log('hii');
$scope.arr.push({
uname:null
});
console.log('hi',$scope.arr);
}
}
</script>
For 1.4 and above use the following. https://plnkr.co/edit/t7STLztqoMiPKaiHr62V?p=preview
<body ng-controller="ContactController">
<p>Hello {{name}}!</p>
<div>
<ul>
<li ng-repeat="r in arr">
<input type="text" ng-model="r.uname">
</li>
</ul>
</div>
Add
app.controller('ContactController', function($scope) {
$scope.name = 'World';
$scope.arr=[{uname:null}];
$scope.create=function(){
console.log('hii');
$scope.arr.push({
uname:null
});
console.log('hi',$scope.arr);
}
});
I'm trying to setup a nested repeat in angular using an associative array of arrays. For example I have a structure as such:
collections['key1'] = [obj1,obj2,obj3,obj4];
collections['key2'] = [obj5,obj6,obj7];
I want to have a view with a structure of:
<div ng-repeat="collection in collections">
<h4>{{collection.id}}</h4>
<div ng-repeat="item in collection">
<span>{{item.name | item.value}}</span>
</div>
</div>
However as soon as I add in ng-repeat="collection in collections" my view becomes blank. Is there a way to do this in angular or will I need to update the way i'm storing my data if I want to loop it in such a way? Thanks.
Just to give you an example how to use it
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.school = {
classes:[
{name:"Class 1", peoples:["Peter","Sue","Marc"]},
{name:"Class 2", peoples:["John","Edward","Sara"]}
]
}
});
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="class in school.classes">
<h4>{{class.name}}</h4>
<div ng-repeat="person in class.peoples">
<label>{{person}}</label>
</div>
<br>
</div>
</div>
</body>
</html>
I currently have this site - http://dev.5874.co.uk/scd-data/ where I have a dropdown which displays results from WP-API which I am pulling in through AngularJS.
It currently combines the two sets of results as they're separate URL's, the results are in categories within a custom post type so if both posts are 'tagged' in the same category chosen they display twice. I need a way to combine the two sets of results but only showing one of the posts - I hope this makes sense. I'm very new to API data and AngularJS and I imagine there is a much simpler way of doing this. Any help would be much appreciated. Here is a snippet of my code to show how it's currently working.
Thanks in advance!
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<style>
.desc {display: none;}
</style>
<script type="text/javascript">
$(function(){
$('.selectOption').change(function(){
var selected = $(this).find(':selected').text();
//alert(selected);
$(".desc").hide();
$('#' + selected).show();
}).change()
});
</script>
<script>
var app = angular.module('myApp', []);
app.controller('northWestCtrl', function($scope, $http) {
var url = 'http://scd.blaze.wpengine.com/wp-json/posts?type=listings&filter[listing_area]=northwest';
$http.get(url).then(function(data) {
$scope.data = data.data;
});
});
</script>
<select class="selectOption">
<option>Search by Region</option>
<option>NorthWest</option>
<option>NorthEast</option>
<option>Midlands</option>
<option>EastAnglia</option>
<option>SouthEast</option>
<option>SouthWest</option>
<option>Scotland</option>
<option>Wales</option>
<option>NorthernIreland</option>
<option>ChannelIslands</option>
</select>
<div id="changingArea">
<body ng-app="myApp">
<div id="NorthWest" class="desc">
<div ng-controller="northWestCtrl">
<div ng-repeat="d in data">
<h2 class="entry-title title-post">{{d.title}}</h2>
<img src="{{d.acf.logo}}">
<div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
<div id="listing-address-1">
{{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
</div>
<div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
<div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
<div id="listing-email">Email: {{d.acf.email}}</div>
<div id="listing-website">Website: {{d.acf.website}}</div>
<div id="listing-established">Established: {{d.acf.established}}</div>
<div id="listing-about">About: {{d.acf.about}}</div>
<div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
<div id="listing-directions">Directions: {{d.acf.directions}}</div>
<div id="scd-link">View on The Shooting Club Directory</div>
</div>
</div>
</div>
</body>
</div>
Here is a working code pen - http://codepen.io/anon/pen/yePYdq
Angular is a great JavaScript front-end framework to choose, and you're off to a good start, but a lot of changes could be made. I've made some suggested changes for easier ways to do things below.
See this CodePen for all changes.
It looks like you've grasped the idea of ng-repeat, but there's definitely a lot of repeated HTML and JS in your view and controller, so let's see if we can do better.
Let's try this without jQuery to avoid direct manipulation of the DOM. And instead of many controllers, we can do this with a single controller.
<div ng-app="MyApp">
<div ng-controller="MyController">
...
</div>
</div>
<script type="text/javascript">
var app = angular.module('MyApp', []);
app.controller('MyController', ...);
</script>
For the dropdown, we'll use ng-repeat in our view and display the names of the shooting types from our model
...
<select ng-model="selectedListing">
<option
ng-repeat="listingShootingType in listingShootingTypes"
value="{{listingShootingType.name}}">
{{listingShootingType.name}}
</option>
</select>
...
<script type="text/javascript">
...
// Our selections/filters
$scope.listingShootingTypes = [
'All',
'Air Rifle/Air Pistol',
'Clay',
'ABT',
'Double Trap',
'English Skeet',
'English Sporting',
'Fitasc',
'Olympic Skeet',
'Olympic Trap',
'Simulated Game',
'Sport Trap/Compact',
'Universal Trench',
'ZZ/Helice',
'Rifle',
'Centrefire Target Rifle',
'Gallery Rifle',
'Muzzle Loading',
'Practice Shotgun',
'Smallbore Rifle'
];
...
</script>
With only one controller, we can still use ng-repeat for each listing.
<div ng-repeat="d in data">
<h2 class="entry-title title-post">{{d.title}}</h2>
<div id="listing-image"><img src="{{d.acf.logo}}"></div>
<div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
<div id="listing-address-1">
{{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
</div>
<div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
<div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
<div id="listing-email">Email: {{d.acf.email}}</div>
<div id="listing-website">Website: {{d.acf.website}}</div>
<div id="listing-established">Established: {{d.acf.established}}</div>
<div id="listing-about">About: {{d.acf.about}}</div>
<div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
<div id="listing-directions">Directions: {{d.acf.directions}}</div>
<div id="scd-link">View on The Shooting Club Directory</div>
</div>
Finally... How do we only display listings that match our selected shooting type from the dropdown? We could use a custom Angular filter!
...
<div ng-repeat="d in data | filter:isSelectedListing">
...
<script type="text/javascript">
...
// Let's define a custom Angular filter because the WordPress JSON is complex
$scope.isSelectedListing = function(listing) {
// Show nothing if nothing is selected
if (angular.isUndefined($scope.selectedListing) || $scope.selectedListing == '') {
return false;
}
// Show all if 'All' is selected
if ($scope.selectedListing == 'All') {
return true;
}
// If the shooting type we're looking for is present, show the listing.
// To do this, we parse the WordPress JSON object model.
if (angular.isDefined(listing.terms.listing_shooting_type)) {
for (var i = 0; i < listing.terms.listing_shooting_type.length; i++) {
if (listing.terms.listing_shooting_type[i].name == $scope.selectedListing) {
return true;
}
}
}
return false;
};
...
</script>
Hopefully this gives you an idea of how we better leverage ng-repeat + DRY :)
The entire CodePen is here.
Today is my first day with Angular.js , and I stuck at a basic controller :
my APP.js
(function()
{ var app = angular.module('store', [ ] );
app.controller('StoreController', function()
{
this.product = gem;
});
var gem = [
{name:'John', price:25, description:'boy',soldout: false,canpurchase:true},
{name:'Kohn', price:25, description:'boy',soldout: false,canpurchase:true}
]
//not mentioned:false
})();
Index.HTML
<!DOCTYPE html>
<html ng-app="store">
<script src="js/angular.min.js" type="text/javascript"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<title>Purple</title>
</head>
<body ng-controller = "StoreController as store">
<script src="js/app.js" type="text/javascript"></script>
<h1>{{"Create your CV"}}</h1>
<div ng-repeat="products in store.product">
<div ng-hide="store.product.soldout">
<h1> {{store.product.name}} </h1>
<h2><em class="pull-right">{{store.product.price | currency}}</em></h2>
<h3> {{store.product.description}} </h3>
<button ng-show = "store.product.canpurchase"> Add to cart </button>
</div>
</div></body></html>
My code is working fine , but NG - repeat is not working, if I don't choose ng-repeat and display each item as an array then I am getting a display but not with "ng-repeat" .. Any idea's what am I missing ?
Please dont mark this as negative, I have done a lot of research before asking this question
Code on fiddle : http://jsfiddle.net/68Dkz/2/
Here is working version using controller alias store as shown. Note that product was changed to products in controller since the array contains more than one product. I think you are gtting confused about which is array and which is the individual item within the ng-repeat due to this
<div ng-repeat="product in store.products">
<div ng-hide="product.soldout">
<h1> {{product.name}} </h1>
<h2><em class="pull-right">{{store.product.price | currency}}</em></h2>
<h3> {{product.description}} </h3>
<button ng-show="product.canpurchase">Add to cart</button>
</div>
</div>
DEMO
store is your module not your scope you don't need it in the iteration, do products in product instead
<div ng-repeat="products in product">
<div ng-hide="products.soldout">
<h1> {{products.name}} </h1>
<h2><em class="pull-right">{{products.price | currency}}</em></h2>
<h3> {{products.description}} </h3>
<button ng-show = "products.canpurchase"> Add to cart </button>
</div>
</div>
stop aliasing your controller, it is unnecessary and may cause issues with the html compiler
using products as your iterator is confusing, I would suggest making the collection products and the iterator product