95

How can I avoid having the {{f = ...}} statement in the third line print out the content of forecast[day.iso]?

I want to avoid using forecast[day.iso].temperature and so on for every iteration.

<div ng-repeat="day in forecast_days">
  {{$index}} - {{day.iso}} - {{day.name}}
  {{f = forecast[day.iso]}}
  Temperature: {{f.temperature}}<br>
  Humidity: {{f.humidity}}<br>
  ...
</div>
Daniel F
  • 13,684
  • 11
  • 87
  • 116
  • 3
    It might not be an answer, but useful tip is to use {{f = forecast[day.iso];""}} as it would not print anything on the view. – Matt Leonowicz Oct 28 '15 at 07:57

2 Answers2

195

Use ngInit: https://docs.angularjs.org/api/ng/directive/ngInit

<div ng-repeat="day in forecast_days" ng-init="f = forecast[day.iso]">
  {{$index}} - {{day.iso}} - {{day.name}}
  Temperature: {{f.temperature}}<br>
  Humidity: {{f.humidity}}<br>
  ...
</div>

Example: http://jsfiddle.net/coma/UV4qF/

PowerKiKi
  • 4,539
  • 4
  • 39
  • 47
coma
  • 16,429
  • 4
  • 51
  • 76
  • 32
    If you want more then one variable just separate them with semicolon ';' – bentzy Oct 29 '14 at 13:08
  • Tip for the uninitiated... depending upon your template structure, you can end up with all records showing only the last value of your variable (in my case, Angular updated the substitutions on a subsequent digest cycle, since they're all bound to the same expression)! To combat this situation, you could assign the variable as a property of the current record being iterated on (if practical to your use case). In the above example, this would become `ng-init="day.f = forecast[day.iso]"` – John Rix Oct 23 '17 at 22:54
37

It's not the best answer, but its also an option: since you can concatenate multiple expressions, but just the last one is rendered, you can finish your expression with "" and your variable will be hidden.

So, you could define the variable with:

{{f = forecast[day.iso]; ""}}
Community
  • 1
  • 1
Zanon
  • 29,231
  • 20
  • 113
  • 126
  • Is this a documented feature? – Daniel F Feb 19 '16 at 18:54
  • @DanielF, I couldn't find. I just saw [this](http://stackoverflow.com/questions/16665319/how-to-set-a-variable-inside-of-a-template#comment54563800_16665319) comment, tested the idea, liked it and decided to add as an answer since it has more visibility and is harder to lose. – Zanon Feb 19 '16 at 19:31
  • @DanielF, just found this high voted [answer](http://stackoverflow.com/a/28432472/1476885) that proposes the same solution. It's also without a doc link. – Zanon Feb 19 '16 at 19:36
  • @DanielF, I've updated my answer. I had to ask [a question](http://stackoverflow.com/q/35517861/1476885) to understand it better. It's not a special feature. Just the behavior of concatenating expressions. – Zanon Feb 20 '16 at 02:07
  • 8
    This hack is especially useful when you want the expression to be bound to scope changes, rather than run once on init. – Ronny Oct 27 '16 at 11:09
  • In a lot of template languages there is two template markers. One for evaluate and the other for replace. This is basically (ab)using Angular's replace template marker to perform arbitrary code evaluation. In Angular, the ng-init directive is the generally prescribed tool for this task. – Eric Rini Apr 05 '17 at 17:44