How do I do nested interpolation in Angular JS - angularjs

I have an ng-repeat that requires nested interpolation to be evaluated. Here is an example:
<div ng-repeat="i in ['1', '2', '3']">
should evaluate to {{ i }}: {{ (i>0) && ( {{ i }} ) || false }}
</div>
This throughs a $parse error. The problem I figure is that Angular can't perform nested evaluation operations, or support nested interpolation.
Is there a way around this problem?

I had a similar issue when trying to create a dynamic table component. With the following code I'm able to display any table from the database on the front end without having to define anything thanks to nested interpolation.
You just need to use square brackets for the nested interpolation.
E.G: {{row[[col.column_name]]}}
<table id="dynamicTable" class="table table-hover" cellspacing="0">
<thead>
<tr>
<th *ngFor="let col of Columns">{{col.column_name}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of Table">
<td *ngFor="let col of Columns">{{row[[col.column_name]]}}</td>
</tr>
</tbody>
</table>
Hope this helps! (Working with Angular 7)

It's giving you parse error because you can't nest {{}}..
{{ code }} basically tells angular that whatever is inside {{ }} (code in my case) is JavaScript, and js doesn't understand {{ }} syntax. This is why second {{ i }} is causing a problem.
You might also want to look at ngRepeat docs - there are some special properties, like $index, that you can use.. https://docs.angularjs.org/api/ng/directive/ngRepeat

I can't understand what's this {{ i }}: {{ (i>0) && ( {{ i }} ) || false }} statement is about , also you cannot have nested {{}} in angular js.
Are you trying to make
Working Demo
<div ng-controller="MyCtrl">
<div ng-repeat="i in ['0','1', '2', '3']">
{{ i>0 ? true: false }}
</div>
</div>

The result of what's in the {{}} will be printed - no need to nest:
<div ng-repeat="i in ['0','1', '2', '3']"> {{ i > 0 ? i : false }} </div>

Related

Angular, idiomatic string replacement?

For some condition, I would like replace a String in my model when displaying it in html. I could do this my modifying my model, but is there a more idiomatic option? Possibly this should be done with a filter?
<tr ng-repeat="i in ctrl.data" >
<td>
<div ng-show="i.category == 'default'">
none
</div>
<div ng-show="i.category != 'default'">
{{ i.category }}
</div>
</td>
</tr>
{{ i.category == 'default' ? 'none' : i.category }}
Or, if you have that in several places, use a filter.

Preparation of links in the loop

There is an array of objects. I sort out of its loop.
In both series to get a link to the image?
vm.data.list- array of object.
Loop:
<tr ng-repeat="item in vm.data.list">
<td ng-bind="item.temp.day"></td>
<td ng-bind="vm.symbal"></td>
<td ng-bind-template="{{ item.humidity }} %"></td>
</tr>
As in the cycle of getting links to the image? (http://openweathermap.org/img/w/vm.data.list[0].weather[0].icon.png, http://openweathermap.org/img/w/vm.data.list[1].weather[0].icon.png and other)
I tried to do so:
<tr ng-repeat="item in vm.data.list">
<td ng-bind="item.temp.day"></td>
<td ng-bind="vm.symbal"></td>
<td ng-bind-template="{{ item.humidity }} %"></td>
<!-- <td img ng-src="http://openweathermap.org/img/w/{{item.weather[0].icon.png}}">-->
<td> <img src=http://openweathermap.org/img/w/{{item}}.weather[0].icon.png></td>
</tr>
you need to use ng-src instead of src: https://docs.angularjs.org/api/ng/directive/ngSrc. Angular will first compute the ng-src value and then construct the src for you.
Here is a basic example: jsfiddle:
<div ng-repeat="item in items">
<img ng-src="http://www.w3schools.com/{{item.f.folders[0]}}/{{item.name}}">
</div>
In your case, use :
<img ng-src="http://openweathermap.org/img/w{{item.weather[0].icon}}.png‌​">
Aside from the ng-src, be aware that:
an url beginning with something else than a protocol or a slash is relative: it will be resolved against the context of the current page. In your case, don't forget the http:// at the beginning !
all the angular expression inside the link should be inside the brackets: {{item}}.weather[0] won't work

Hide table header if no results after filter

I have a table containing some data. And i have to filters on this data.
When, after filtering data, there is no results, i want to show a "no results" message, and it works.
But i also want to hide the table completely when there are no results.
Here is a demo :
http://plnkr.co/edit/iSbr9Ij4wsX947JqAsEB?p=preview
I tried :
<table ng-if="results.length > 0">
But that gave me a js error
Is there a way to hide the table if there are no results to show ?
Thanks a lot
this does not feel right, but it works :)
<tr ng-repeat="x in accueils | filter:{annee:annee.id} | filter:myFilter as results" ng-if="$first">
<th>column1</th>
<th>column2</th>
</tr>
EDIT This feels nicer .
<header ng-repeat-start="item in items">
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer ng-repeat-end>
Footer {{ item }}
</footer>

Significance of ng-repeat-start vs ng-repeat

I am trying to understand the significance of ng-repeat-start over ng-repeat. The angular documentation provides the following example for ng-repeat-start
<header ng-repeat-start="item in items">
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer ng-repeat-end>
Footer {{ item }}
</footer>
But the same can be achived using ng-repeat,
<div ng-repeat="item in items">
<header>
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer>
Footer {{ item }}
</footer>
</div>
Can someone explain the significance of ng-repeat-start.? Thanks.
I thought I'd add my answer, as no one touched on a very important reason for having these directives available. ng-repeat will not work correctly in certain scenarios when using html tables. Using ng-repeat-start is the only way to accomplish certain things.
Imagine you want to display your data like this using html tables:
And this is your data set:
groups = [
{
name: "Group 1",
customers: [
{id: 123, name: "Foo Inc.", state: "NJ"},
{id: 234, name: "Bar Co.", state: "AZ"}
]
},
{
name: "Group 2",
customers: [
{id: 345, name: "Baz LLC", state: "CA"}
]
}
];
Using ng-repeat-start and ng-repeat-end you can do this:
<table>
<tr>
<th>ID</th>
<th>Customer</th>
<th>State</th>
</tr>
<tr ng-repeat-start="group in groups">
<td colspan="3" style="text-align:center">{{group.name}}<td>
</tr>
<tr ng-repeat-end ng-repeat="customer in group.customers">
<td>{{customer.id}}</td>
<td>{{customer.name}}</td>
<td>{{customer.state}}</td>
</tr>
</table>
Notice the ng-repeat-end followed by another regular ng-repeat. This ends the matching ng-repeat-start but initiates another repeat on the customers array, since we are still in the original ng-repeat-start scope when calling ng-repeat-end, we still have access to the group object.
Keep in mind, this is a very trivial example, but as the table structure becomes more complicated, the only way to accomplish things like this is to use ng-repeat-start and ng-repeat-end
The significance of these two directives is similar: they repeat HTML-tags. The difference is only that with help of ng-repeat-start you could repeat few tags starting from tag with ng-repeat-start and finishing by ng-repeat-end.
For example you have next code:
<div>
Item # {{item}}
</div>
<div>Whether you repeat me?</div>
So now we can add 2 directives for these code.
With ng-repeat:
<div ng-repeat="item in items">
Item # {{item}}
</div>
<div>
This code will not be repeated
</div>
With ng-repeat-start and ng-repeat-end:
<div ng-repeat-start="item in items">
Item # {{item}}
</div>
<div ng-repeat-end="">This code will be repeated</div>
So now you can see that in the first case just div with ng-repeat directive repeats, but in the second case both your divs will be repeated.
You can see Demo and play with it:
Demo: http://plnkr.co/edit/R778lWTABVF3Hy16CAca
The ng-repeat-start directive works the same as ng-repeat, but will repeat all the HTML code (including the tag it’s defined on) up to and including the ending HTML tag where ng-repeat-end is placed

Haml interpolation with underscore template variable

I am trying to output an underscore template variable in my haml template but I'm not having any luck.
The HTML is not being escaped so I can't seem to figure out why the underscore variable isn't rendering.
HAML - Full Template
%script{:type => "text/template", :id => "user_list_template"}
%h4 Users
#test
%table.table.table-bordered
%thead
%tr
%th #
%th Name
%th Nickname
%th
%tbody
{{ _.each( users, function(user) { }}
%tr
%td {{= user.get('id') }}
%td {{= user.get('name') }}
%td {{= user.get('nickname') }}
%td
%a.btn{:href => "{{= user.get('nickname') }}"}
View User
{{ }); }}
The source
<tr>
<td>9</td>
<td>TacoHell</td>
<td>TacoHelll</td>
<td>
<a class="btn" href="<%= user.get('nickname') %>">
View User
</a>
</td>
</tr>
Console.log of template
<h4>Users</h4>
<div id='test'></div>
<table class='table table-bordered'>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Nickname</th>
<th></th>
</tr>
</thead>
<tbody>
{{ _.each( users, function(user) { }}
<tr>
<td>{{= user.get('id') }}</td>
<td>{{= user.get('name') }}</td>
<td>{{= user.get('nickname') }}</td>
<td>
<a class='btn' href="{{= user.get('nickname') }}">
View User
</a>
</td>
</tr>
{{ }); }}
</tbody>
</table>
I have read through previously asked question but cannot get it to work. Any ideas?
Interpolating underscore.js template with HAML
Rendering “<%%=” with HAML
Interpolate inside html attributes with Underscore.js
Edit 1
Added full template
Edit 2
console.log of template
This isn't so much a solution as it is a workaround, but one alternative would be to use a different syntax for your Underscore templates (one that doesn't involve < and >). If you look at:
http://documentcloud.github.com/underscore/#template
you'll find they provide an example of alternate Django/Mustache-style template syntax:
If ERB-style delimiters aren't your cup of tea, you can change
Underscore's template settings to use different symbols to set off
interpolated code. Define an interpolate regex to match expressions
that should be interpolated verbatim, an escape regex to match
expressions that should be inserted after being HTML escaped, and an
evaluate regex to match expressions that should be evaluated without
insertion into the resulting string. You may define or omit any
combination of the three. For example, to perform Mustache.js style
templating:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
var template = _.template("Hello {{ name }}!");
template({name : "Mustache"});
=> "Hello Mustache!"
Of course, if you were considering looking in to a more powerful templating system anyway, then it certainly wouldn't hurt to abandon _.template and use Mustache, Handlebars, or a similar templating system instead. But if you're happy with Underscore, the _.templateSettings.interpolate will let you use it without < or >.

Resources