Add template conditionally in Angular - javascript

I have some data:
$scope.posts = [
{ 'name' : 'post1', 'templateName' : 'template1.html' },
{ 'name' : 'post2', 'templateName' : 'template2.html' }
]
...and I have two templates:
<script type="text/ng-template" id="template1.html">
<p><span>{{post.name}}</p></li>
</script>
<script type="text/ng-template" id="template2.html">
<p>{{post.name}}</p>
</script>
They are to be inserted into a list that is backed by $scope.posts, which in turn is listed with:
<li ng-repeat="post in posts"></li>
How do I iterate over $scope.posts and insert the right template, based on 'templateName', but also populate it with post.name?

I would use ngIf for something like this, you can also use ngSwitch
<p ng-if="post.templateName == myTemplate"></p>
<p ng-if="post.templateName == myOtherTemplate"></p>

So I ended up doing the following:
<li ng-repeat="post in posts">
<ng-include src="post.template"></ng-include>
</li>

Just to be safe:
<li ng-repeat="post in posts">
<div ng-include="post.templateName"></div>
</li>
In case some Browsers(IE) don't like non standard tags.

Related

How to display last part of string containing multiple dots inside ng repeat?

Below are my list of items :
$scope.items = [
{id=1,name:'code.lmn.1234.Lodashjs'},
{id=2,name:'xyz.Suv.Angularjs'},
{id=3,name:'www.kius.reactjs'}
]
Now I want to display last part of name so expected output is like below :
Lodashjs
Angularjs
reactjs
I don't want to create filter for this as that will impact performance. So is there any way to do this without filter?
var app = angular.module("myApp", []);
app.controller("myController", function ($scope) {
$scope.items = [
{id:1,name:'code.lmn.1234.Lodashjs'},
{id:2,name:'xyz.Suv.Angularjs'},
{id:3,name:'www.kius.react.js'}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="item in items">
<span >{{item.name}}</span>
</div>
</div>
Try this:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="item in items">
<span >{{ item.name.split('.').reverse()[0] }}</span>
</div>
</div>
Yes it's so simple.
Just copy paste the below code:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="item in items">
<span >{{(item.name).substr((item.name).lastIndexOf('.') + 1, (item.name).length)}}</span>
</div>
</div>
You can also use directive that will manipulate the name and return string after last "." dot.
<div ng-repeat="item in items" my-directive my-directive-fn="item.name">
app.directive("myDirective", function(){
return {
scope: {
"myDirectiveFn": "="
},
link: function(scope){
scope.myDirectiveFn.match(/([^.]+)$/);
}
}
});

Angular - loop over nested javascript arrays

How can I use ng-repeat to loop over data that contains many nested array data?
I have data that will have many "Segments"
Example:
confirm.booking.flightData[0].Segments[0].FlightNumber
confirm.booking.flightData[0].Segments[1].FlightNumber
confirm.booking.flightData[0].Segments[2].FlightNumber
I have done both ng-repeat with angular, and without angular I would end up resorting to javascript that loops over data and creates the html dynamically, but I wish to do this the ANGULAR way.. HOW?
HTML with Angular/Javascript Arrays:
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
<span style="font-weight: bold;">Flight</span>
</div>
<div class="col-md-4">
<span style="font-weight: bold;">Departs</span>
</div>
<div class="col-md-4">
<span style="font-weight: bold;">Arrives</span>
</div>
</div>
<div class="row">
<div class="col-md-4">
{{confirm.booking.flightData[0].Segments[0].FlightNumber}}
</div>
<div class="col-md-4">
({{confirm.booking.flightData[0].Segments[0].DepartureAirport}})
</div>
<div class="col-md-4">
({{confirm.booking.flightData[0].Segments[0].ArrivalAirport}})
</div>
</div>
</div>
Nesting can be done in repeats, but repeating too much in ng-repeats can be costly in terms of performance as angular creates scopes for each element repeated. Hence, filtering data till the perfect abstracted values that you need in terms of html should be done in the js file.
For eg: if u need only segements in the html form do this, or if u need even flight data in html form follow #Rachel's post
<ul data-ng-repeat="item in confirm.booking.flightData[0].Segments">
<li>{{ item.FlightNumber}}</li>
</ul>
Let's say your data is in flightdetails, then you can go about it like this:
<div ng-repeat="a in flightdetails ">
<div ng-repeat="b in a.booking">
<div ng-repeat="c in b.flightdata">
<div ng-repeat="d in c.segments">
{{d.flightnumber}}
</div>
</div>
</div>
</div>
You can use nested ng-repeat to bind your data - see a demo below:
angular.module("app", []).controller("ctrl", function($scope) {
$scope.confirm = {
booking: {
flightData: [{
Segments: [{
FlightNumber: 1
}, {
FlightNumber: 2
}]
}, {
Segments: [{
FlightNumber: 3
}, {
FlightNumber: 4
}]
}]
}
}
// console.log($scope.confirm);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="wrapper" ng-app="app" ng-controller="ctrl">
<div ng-repeat="x in confirm.booking.flightData">
Data {{$index + 1}}:
<div ng-repeat="y in x.Segments">
<div>Flight No: {{y.FlightNumber}}</div>
</div>
<br/>
</div>
</div>
If you want to display only the following:
confirm.booking.flightData[0].Segments[0].FlightNumber
confirm.booking.flightData[0].Segments[1].FlightNumber
confirm.booking.flightData[0].Segments[2].FlightNumber
then you can use limitTo - see demo below:
angular.module("app", []).controller("ctrl", function($scope) {
$scope.confirm = {
booking: {
flightData: [{
Segments: [{
FlightNumber: 1
}, {
FlightNumber: 2
}]
}, {
Segments: [{
FlightNumber: 3
}, {
FlightNumber: 4
}]
}]
}
}
// console.log($scope.confirm);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="wrapper" ng-app="app" ng-controller="ctrl">
<div ng-repeat="x in confirm.booking.flightData | limitTo : 1">
Data {{$index + 1}}:
<div ng-repeat="y in x.Segments">
<div>Flight No: {{y.FlightNumber}}</div>
</div>
<br/>
</div>
</div>
I created an example here:
http://codepen.io/ackzell/pen/ENBymo
It ultimately looks like this, but check the pen as it has some more info:
<ul>
<li ng-repeat="flight in vm.flightData">
<ul>
<li ng-repeat="segment in flight.Segments">
<em>FlightNumber</em> {{ segment.FlightNumber }}
<br />
<em>Departure:</em> {{ segment.DepartureAirport }}
<br />
<em>Arrival:</em> {{ segment.ArrivalAirport }}
</li>
</ul>
</li>
</ul>
Nesting ng-repeats would help, but maybe you want to give your data some treatment first.

What does equals in ngRepeat do?

What does the equals in the ng-repeat attribute value mean?
<li ng-repeat="person in people = (people | orderBy: firstname)">
instead of doing:
<li ng-repeat="person in people | orderBy: firstname">
I can't see any examples explaining its use in the documentation for ngRepeat.
It is usefull for count how many objects were filtered, eg.
function People($scope) {
$scope.people = [{
firstname: 'a'
}, {
firstname: 'c'
}, {
firstname: 'b'
}, {
firstname: 'c'
}]
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="People">
<ul>
<li ng-repeat="person in filteredPeople = (people | filter: 'c')">{{person.firstname}}</li>
</ul>
Total filtered: {{ filteredPeople.length }}
</div>
#Krzysztof - There is no requirement of "=" operator usage to show number of objects filtered. It can be done without it. So, you are completely wrong.
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<p ng-repeat="x in people | orderBy: 'age'">{{x.name}},{{x.age}}</p>
<p>Total Filtered: {{people.length}}</p>
<script>
//Module declaration
var app = angular.module('myApp',[]);
//controller declaration
app.controller('myCtrl',function($scope,$timeout){
$scope.people = [{name:"Peter",age:15},{name:"Julie",age:28},{name:"Roger",age:17}];
});
</script>
</body>
</html>

AngularJS Filter by ID

I have the following Json_encode FRom PHP Response...
[
{"ID":"149","IDusr":"4","aut_more_info":"good","doc_name":"img1838142879.jpeg","doc_type":"jpg"},{"ID":"149","IDusr":"4","aut_more_info":"good","img5733250433.jpeg","doc_type":"jpg"},{"ID":"149","IDusr":"4","aut_more_info":"good","doc_name":"img1230306801.jpg_doc","doc_type":"jpg"}
]
And I have tried the https://github.com/a8m/angular-filter Plugin. Here is my code.
<div ng-repeat="(key, value) in Detail | groupBy: 'ID'">
<div ng-repeat="aut in value">
<div class="item item-avatar bar bar-calm">
<h2>{{aut.name}} {{aut.model}}</h2>
</div>
<div class="item item-avatar">
<img src="../www/img/icon/{{aut.doc_name}}">
</div>
</div>
</div>
AS you see from the Array, I have the same ID but the doc_name is different, Means I want to show the ID once but the three Images should be shown as well. How can I achieve that?
Thanks in advance...
You have an error in your JSON whereby you are missing a property name.
Plunker.
angular.module('foo', ['angular.filter'])
.controller('bar', ['$scope', function($scope){
$scope.Detail = [
{
"ID" : "149",
"IDusr" : "4",
"aut_more_info" : "good",
"doc_name" : "img1838142879.jpeg",
"doc_type" : "jpg"
},
{
"ID" :"149",
"IDusr" :"4",
"aut_more_info" :"good",
// you were missing the property name 'doc_name' here...
"doc_name" :"img5733250433.jpeg",
"doc_type" :"jpg"
},
{
"ID" :"149",
"IDusr" :"4",
"aut_more_info" :"good",
"doc_name" :"img1230306801.jpg_doc",
"doc_type" :"jpg"
}
];
}]);
Also you seem to be trying to render values for properties that don't exist in your JSON data
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body ng-app="foo">
<div ng-controller="bar">
<div ng-repeat="(key, value) in Detail | groupBy: 'ID'">
<div ng-repeat="aut in value">
<div class="item item-avatar bar bar-calm">
<!-- you don't have properties name or model in your json -->
<h2>{{aut.name}} {{aut.model}}</h2>
</div>
<div class="item item-avatar">
<img src="../www/img/icon/{{aut.doc_name}}">
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js"></script>
<script src="script.js"></script>
</body>
</html>
I think there's a conceptual error in your JSON (apart the one noticed by #A.Alger).
I like the uniqueness of an ID. For instance, in a simple database table your ID (primary key) is showed exactly one time for each select. If you make some join operations that ID can be present more than one time. This is fine, since database table (and select) lack the expressivity that JSON indeed have, so I will return a json like this:
[{
"ID": "149",
"IDusr": "4",
"aut_more_info": "good",
"docs": [{
"doc_name": "img1838142879.jpeg",
"doc_type": "jpg"
}, {
"doc_name": "img5733250433.jpeg",
"doc_type": "jpg"
}, {
"doc_name": "img1230306801.jpg",
"doc_type": "jpg"
}]
}]
In this way the documents are naturally grouped together, and you can use your angular without any plugin:
<div ng-repeat="user in users">
ID: {{user.ID}} - IDusr: {{user.IDusr}}
<h5>Images</h5>
<div ng-repeat="doc in user.docs">
{{doc.doc_name}} <br>
{{doc.doc_type}}
<hr>
</div>
</div>
This is a plunker that show how it works.

Cannot get angular.isString to work with ng-repeat

I'm trying to do an angular.isString comparison with ng-if inside an ng-repeat. But all items in the array are returned.
So I tried to just output the angular.isString result but it doesn't output anything.
Here is what I would like to do:
<li ng-repeat="item in data">
<div ng-if="angular.isString(item)">
{{ item }}
</div>
</li>
function MyCtrl($scope)
{
$scope.data =
[
"Hello",
"-",
123
];
}
Here's a fiddle: http://jsfiddle.net/m6k13whh/2/
Angular expressions are evaluated against the scope. You can create a function which returns angular.isString:
<li ng-repeat="item in data">
<div ng-if="isString(item)">
{{ item }}
</div>
</li>
$scope.isString = function(item) {
return angular.isString(item);
}
You can also just filter all of the items with that function:
<li ng-repeat="item in data | filter:isString">
<div>
{{ item }}
</div>
</li>
The best solution is to pass reference to angular method into scope
$scope.isString = angular.isString
then in partial you can just use ng-if="isString(item)"
http://plnkr.co/edit/5keCUQrHQnbl4Wg0oKp1?p=preview
Hej,
Make sure you only import one library.
Because in the fiddle you have include two angular scripts.
Remove the one in External Resources!
<div ng-app="myApp" ng-controller="MyCtrl">
<!-- this if comparison is what I want to do -->
<ul>
<li data-ng-repeat="item in data">
<div data-ng-if="isString(item)">
{{ item }}
</div>
</li>
</ul>
</div>
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.data = [
"Hello",
"-",
123
];
$scope.isString = function(value) {
return angular.isString(value);
};
});

Categories