2

I have an Angular app where data is loaded in through JSON files. For the various objects, one of the properties is a "Description". In my app I pop it in my html via {{item.Description}}. My problem is that the string in the JSON file has values that need to be adjusted based on a variable. For example, "The value is 160 (+20 per var)". I would like this description to read out 160 plus 20 times the value of the provided variable.

Unfortunately I can't just put {{160+(20*var)}} in the description, because it just prints out the expression as string.

Is there anyway to create that binding in angular so it updates dynamically based on the other variable?

Update As per request I'm adding as much code as I can.

In my file's head I'm including a JSON file with:

<script src="path/to/file.json"></script>

Then, I have my controller:

app.controller('itemController', function(){
    this.items = Items //Items is declared in the JSON file as the JSON object.
});

Then in my HTML I call:

<div ng-controller="itemController as ctrl">
    <span class="description" ng-repeat="item in ctrl.items">
        {{item.Description}}
    </span>
</div>

The problem is, that item.Description has expressions I would like to evaluate. I would normally just do {{160+(20*ctrl.var)}}, but since that expression is contained in the item.Description string, Angular doesn't evaluate it normally.

sharf
  • 2,123
  • 4
  • 24
  • 47
  • Could you share some code? The requirement is not very clear, it would be really helpful to see some code. – Roco CTZ May 03 '15 at 02:09
  • @RocoCTZ There is no relevant code yet really. All I'm doing is including a JSON file, assigning it to a variable and then outputting it to the file. I'll update my question with some code, but there is nothing really. – sharf May 03 '15 at 02:35

1 Answers1

3

It appears you can do this by replacing {{item.Description}} with {{$eval(item.Description)}}, which will evaluate a string as an Angular expression. See the Angular docs for expressions, or a StackOverflow post about $eval.

Edit: OP has clarified that item.Description may contain mixed Angular expressions and other text, for example "The value is {{85 + 22 * ctrl.var}}". Fortunately the Angular docs for $compile contain an example that solves this exact problem! Here is a brief demo.

angular.module('app', [])
  .directive('compile', function($compile) {
    // directive factory creates a link function
    return function(scope, element, attrs) {
      scope.$watch(
        function(scope) {
           // watch the 'compile' expression for changes
          return scope.$eval(attrs.compile);
        },
        function(value) {
          // when the 'compile' expression changes
          // assign it into the current DOM
          element.html(value);

          // compile the new DOM and link it to the current
          // scope.
          // NOTE: we only compile .childNodes so that
          // we don't get into infinite loop compiling ourselves
          $compile(element.contents())(scope);
        }
      );
    };
  })
  .controller('itemController', function() {
    this.var = 5;
    this.items = [
      {Description: "What's 1+1? It's {{1+1}}"},
      {Description: "The value is {{85+22*ctrl.var}}"},
      {Description: "He{{'llo'}} World!"}
    ];
  });
body {
  font-family: sans-serif;
}
#main > span {
  background-color: #ddd;
  padding: 8px 16px;
  margin: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="app" class="ng-scope">
  <h1>Compile Test!</h1>
  <div ng-controller="itemController as ctrl" id="main">
    <span class="description ng-scope" ng-repeat="item in ctrl.items" compile="item.Description"></span>
  </div>
</body>
gengkev
  • 1,890
  • 2
  • 20
  • 31
  • When I try running that I get a Error: `$parse:syntax Syntax Error`. It doesn't like the {{ in the `item.Description`. Upon reading the links I notice mention of special syntax, but can't find it... – sharf May 03 '15 at 03:29
  • Could you simply not output the {{ }} in `item.Description`? If not, you can remove it manually with a loop inside the controller. – gengkev May 03 '15 at 03:31
  • I've changed `item.Description` to have it without the {{ }}, so I have 85+(22*var) and I still get a syntax error starting at the 85 – sharf May 03 '15 at 03:40
  • I see the problem. `$eval` produces an error when I try to use it on string, which is what `item.Description` is. I need it to evaluate the expression in the middle of a string. – sharf May 03 '15 at 03:43
  • No, `$eval` is supposed to take a string... if you put `{{ 85 + (22 * var) }}` directly into the body, does it work correctly? – gengkev May 03 '15 at 03:55
  • if I change `item.Description` to "85+(22*var)" it does the appropriate calculation and outputs the right number. If I put {{85+(22*var)}} in the same spot as `{{$eval(item.Description)}}` it outputs the right number. As soon as I put text into `item.Description` I get a syntax error. – sharf May 03 '15 at 04:13
  • So it works as I expected, but perhaps not as you did. Do you mean that the description will be a mix of text and Angular expressions, for example, `The value is {{85+22*var}}`? – gengkev May 03 '15 at 04:18
  • Yes, what I meant when I said string was Text in addition to the expression. I need the description to be a combination of text and an expression such as `The value is {{85+22*var}}` – sharf May 03 '15 at 04:43