Interpolating variables within already interpolated strings in angular - javascript

I have the following arrangement to fetch helptexts from a single Coffeescript file.
Coffeescript:
help.ex: '{{example.variable}} identifies enterprise data centers'
HAML:
%example-directive(attr='{{help.ex}}')
Now the example.variable is accessible but it is not getting interpolated on the view. This I guess is happening because the string as a whole is getting interpolated and compile is not running on the variables within. How do I get around this?

You can use the $interpolate service:
var exp = $interpolate(attrs.attr) // interpolate your attriubte
var interpolated = exp(scope) // evaluate it with the scope variable
Check this plunker

Related

Knockout.js: how to make a variable available to all viewmodels so it can be used in bindings without explicitly putting it in all viewmodels?

I am refactoring code base based on Knockout.js and have stumped into a problem.
The code uses templates as interpolated strings in typescript eg.
var template = `<div title='${Resources.string1}'> ${Resources.string1} </div>`
The problem is that the strings can contain a single quote which sometimes break the proper HTML parsing after it has been compiled to javascript.
var template = `<div title='I have a ' single quote'> I have a ' single quote</div>`
I want to expose the Resources object so that it is visible in all the view models without explicitly adding the resource object to every view model so that I can use it like this
<div data-bind="title: Resource.string1"> ${Resources.string1} </div>
Or is their anything global to which I can bind this resources object and access it from all view models inside my app.
You can refer to a global variable without any problem.
This one works, here is a demo fiddle.
var Resources = {
string1: "something here with ' quote"
}
window.Resources = Resources;
ko.applyBindings({});
<div data-bind="text: Resources.string1">
</div>
However, this feels like kind of a hack. I'd rather use some HTML encoding for the resources. See some possibilities here. I'd add a getResource function which would return the requested resource in a properly encoded form.

dynamic translation/translation with variable with i18next

How come I can't translate dynamically resp. using a variable with i18next?
For example in my JS-file I got this:
Here I use a variable and assign it to the i18n function and it doesn't work:
//this does not work:
var dynamicTranslation = "myText.toBetranslated";
console.log("translation dynamic ", !{JSON.stringify(t(dynamicTranslation))});
Here I hardcoded the string from above directly into the i18n function and it does work:
//inserted string is the same string as in dynamic translation but this does work:
console.log("translation static ", !{JSON.stringify(t("myText.toBetranslated"))});
As a result I get:
translation dynamic
translation static correct Translation
In order to solve it, I tried to solve it by playing around with setTimeout:
setTimeout(function() {console.log("time out translation: " + !{JSON.stringify(t(dynamicTranslation))})}, 2000);
But it would still show an empty result:
time out translation:
It's jade syntax. The first code didn't work because it is rendered with jade at the back end site. At that point jade doesn't take the JS part into consideration but only renders it and pushes the result (along with the untouched JS code) to the front end. Therefore the part with the variable inside the t()-function is not translated, because it doesn't take the JS code into consideration.

Can $parse or $eval be used to evaluate a stingified boolean equation?

I'm trying to understand $parse and $eval better and figure out if they are (or can be) used in a manner that I thought possible. I've created a plnkr to show my issue/question and reference their lines
I have an object with a boolean expression as a string value, which will be served to me from an external source (script.js line 6-10):
$scope.input123456abcdefg;
$scope.object123456abcdefg = {
disabled: "input123456abcdefg == 'hello'"
};
I have tried a few code walkthroughs, all of which have basically boiled down to (my understanding) of these 2 types of operations/functions (script.js line 12-15):
var template_v1 = $parse('object123456abcdefg.disabled');
$scope.expression_v1 = template_v1($scope);
$scope.expression_v2 = $scope.$eval('object123456abcdefg.disabled');
What I'm expecting (hoping) for either $parse or $eval to do is create an equivalent to (script.js line 17):
$scope.expression_v3 = $scope.input123456abcdefg == 'hello';
However, I'm only returned the same string as when I started, which you can see evaluated on the DOM (index.html lines 24 & 28).
Can $parse or $eval be used in this fashion, and if so where am I dropping the ball at? Or is there another option in Angular that is correct for performing this type of action?
As suggested by #dandavis I'd avoid eval() altogether if possible.Here a small explanation from MDN
Why do you require the value of object123456abcdefg.disabled to be passed in?
EDIT: If you really could not find another way of doing so, this is how you make your code work:
$scope.expression_v2 = $scope.$eval($scope.object123456abcdefg.disabled);

Difference between interpolation and concatenation in JavaScript?

The language and library I'm using is JS and AngularJS. Am I right in assuming that "interpolation" and "concatenation" both means "combination of strings and variables"?
But "interpolation" is used when you're using the double curly brackets in AngularJS. And "concatenation" is used when you're using pure JS?
Or is there another diference that I missed?
EDIT:
Is this interpolation or concatenation (I don't just put strings together but an a variable is resolved here)?
var test1 = "Hello";
var number = 2 + 3;
console.log(test1 + " " + number);
Hmm.... I guess whenever I use AngularJS library to combine some expression, then it's interpolation, right?
In Angular js interpolation helps in getting model render on the view. Where as concatenation is to allow the strings to be join together with '+' it may or may not include interpolation .
Example:-
{{}} --> interpolation
It allows your model to bind in view:-
Model:- $scope.name="rachit";
View:- <div>{{name}}</div>
result in View after rendering :- <div>rachit</div>
'+'-->concatenation
It allows to concat the values either in view or in controller or even inside interpolation.
Controller:-
$scope.name="rachit"+"gulati";
View
<div>{{name+name}}</div> //Here interpolation also comes into picture.
result:-"<div>rachitgualtirachitgualti</div>"
UPDATE 1:-
EDIT: Is this interpolation or concatenation (I don't just put strings
together but an a variable is resolved here)?
var test1 = "Hello";
var number = 2 + 3;
console.log(test1 + " " + number);
It is simple concatenation in javascript here angular is not come into picture.
UPDATE 2:-
Hmm.... I guess whenever I use AngularJS library to combine some
expression, then it's interpolation, right?
Concatenation is general term for every programming to concat two strings together.Where as in angualr js interpolation is done by {{}} with the help of $interpolation service.
Interpolation
Interpolation does mean that you want to get the code from the angular scope and show it on html page like suppose we have {{somevariable}} In this eg. it will evaluate the function in angular scope using $interpolation service.
Concatenation
It is used when you want to bind to two strings, It could be do it inside interpolation {{}} directive like {{someVariable + ' test'}} it will concate variable with test result would be someVariable test
Interpolation basically means that an expression gets resolved and concatenation is when you put a string together.

How to know if $interpolate fails in AngularJS 1.2?

I'm trying to use the $interpolate service in AngularJS 1.2.16. However, I don't know how to check if Angular has properly interpolated all the vars in my string or not.
I noticed in AngularJS 1.3 they have added a new parameter AllOrNothing, which will cause the interpolate function to return an undefined if any embedded expressions fail to evaluate fully.
Any ideas how I can perform a similar check in 1.2? I would be okay looking for any embedded expressions, but Angular will strip them from the string if they are not specified in the context, so I can't even look for non-evaluated tokens in the returned string.
Use a unit test:
var exp = $interpolate('Hello {{name | uppercase}}!');
expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
References
AngularJS Source: interpolateSpec.js

Categories

Resources