1

I'm pulling JSON data from a server. Inside the JSON object I'm returning, I have strings that I want to be able to use placeholders with to dynamically insert values entered by the user in the UI.

My understanding is that this is what $compile is for, but I can't seem to get that to work. I'm not sure if this is possible or if I'm just approaching it the wrong way.

Edit: Not sure if I'm explaining well. Got a little further and I updated the Plunk and the code below

A simplified example (view Plunk):

View:

<body ng-controller="MainCtrl">
    <input ng-model="name" type="text" />
    <p ng-bind-html="myval">{{myval}}</p>
    <p>{{name}}</p>
  </body>

Angular App:

var app = angular.module('plunker', ['ngSanitize']);

app.controller('MainCtrl', function($scope, $compile, dataSvc) {
  init();

  function init() {
    $scope.data = dataSvc.getData();
    $scope.name = '';
  }

  $scope.$watch('name', function(newVal, oldVal) {
    var c = $compile('<span>' + $scope.data.vals[0].text + '</span>')($scope);
    console.log(c);
    console.log(c[0]);
    $scope.myval = c[0];
  });
});

app.service('dataSvc', function () {
  this.getData = function () {
    return {
      vals: [
        {
          text: "Hello {{name}}"
        }
      ]
    }
  };
});

This almost works with $compile and the console logs the changes the way I want them to happen, I just can't get it to output on the display.

4
  • This feels like an XY problem. Angular doesn't actually have a service to perform this kind of interpolation, because by the time this string is rendered in the browser, the $digest cycle is already complete. you could use a directive and inject the element by hand, but really, there are few reasons that you would store client side expressions in their raw state in the database in the first place.
    – Claies
    Commented Aug 7, 2015 at 19:16
  • @Claies There is a reason for it and $compile is working, I'm just missing something in it's use. See updates above. Commented Aug 7, 2015 at 19:53
  • compile doesn't work that way; compile creates an element that needs to be added to the elements collection on the page by hand. aside from that, I still contend that the server has no business at all transmitting client side code.
    – Claies
    Commented Aug 7, 2015 at 20:01
  • @Claies Any suggestions on an alternative? Commented Aug 7, 2015 at 20:07

4 Answers 4

3

I'd suggest you to use $interpolate service while assigning variable to other, which will take care of evaluation of curly braces.

Code

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $interpolate) {
  $scope.test = "Hello {{name}}!";
  $scope.name = 'World';

  init();
  function init() {
    $scope.concat = $interpolate($scope.test)($scope);
  }
});

Working Plunkr

1
  • Thank you! Exactly what I was looking for. Commented Aug 7, 2015 at 20:32
0

Why don't you write something like this :

$scope.greetingText = "Hello";
$scope.greetingName = "World";

and then

$scope.completeGreeting = $scope.greetingText + $scope.greetingName + "!";

and now in view something like this :

{{greetingText}} {{greetingName}}!

{{completeGreeting}}

4
  • See comment on @Rorschach120's answer. Commented Aug 7, 2015 at 19:01
  • why don't you then use regex to search for {{}} in the string and replace the enclosed string part with veriable values??
    – binariedMe
    Commented Aug 7, 2015 at 19:04
  • Most probably overriging string concatenation method will be handy
    – binariedMe
    Commented Aug 7, 2015 at 19:04
  • The JSON object is being built dynamically on the server so there's no guarantee what string I'm looking for. Commented Aug 7, 2015 at 19:06
0

Unless you are using ECMA6, brackets({{}}) are reserved for interpolating strings in HTML, not javascript.

To achieve what you want in javascript just add the variable to the string:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.test = "Hello " + $scope.name + "!";

  init();
  function init() {
    $scope.concat = $scope.test;
  }
});

IF you want the JSON to update the name asynchronously or any time after compilation then using a scope variable in the view is exactly what you should do:

<body ng-controller="MainCtrl">
  <p>Hello {{name}}!</p>
</body>

And then in your controller:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';

  function updateName(name) { // call this when the data is ready
    $scope.name = name;
  }
});
6
  • Like I said in my question, the strings are part of a JSON object that's being pulled from the server so this doesn't work. Commented Aug 7, 2015 at 19:01
  • check my edit. You can assign that JSON value to the name. Angular will update the scope and the view will change as soon as the data is ready and you call that function with jsonObj.path.to.name as the callback. Commented Aug 7, 2015 at 19:05
  • If you post the code for loading the JSON I can show you more specifically. Commented Aug 7, 2015 at 19:05
  • Doesn't work, the string is being pulled entirely from the server, the view and the controller need to work without knowing what's contained in the string. Commented Aug 7, 2015 at 19:09
  • 1
    So you don't have a reference to the string? You aren't storing it anywhere? Whatever it's value is you still need to be able to access that data through variable. Commented Aug 7, 2015 at 19:11
0

I edited your Plnkr, with an input box combined with ngModel. It will output any string you enter in the inputmodel. As I understand you want to output strings which are entered by a user in a UI, so this might work for you.

  <body ng-controller="MainCtrl">
    Name: <input ng-model="userInput" placeholder="Enter your input..."/><br>
    <p>{{userInput || "User input will come here..."}}</p>
  </body>

Plunker

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.