Use angular translate with parameters and HTML - angularjs

I have a translation label with parameters and html :
{
"myLabel": "There is <b>{{param}}</b> value."
}
I don't arrive to pass my parameter and to get the HTML interpreted. I try many option :
Option 1 : Use ng-bind-html with translate filter
<p ng-bind-html="{{'myLabel' | translate:{param: vm.myParam} }}"></p>
But I get this error :
angular.js:14642 Error: [$parse:syntax] http://errors.angularjs.org/1.6.5/$parse/syntax?p0=%7B&p1=invalid%20key&p2=2&p3=%7B%7B'general.help.notion.text3'%20%7C%20translate%3A%7BnbButton%3A%20vm.nbBtn%7D%20%7D%7D&p4=%7B'general.help.notion.text3'%20%7C%20translate%3A%7BnbButton%3A%20vm.nbBtn%7D%20%7D%7D
at angular.js:88
at r.throwError (angular.js:15200)
at r.object (angular.js:15189)
at r.primary (angular.js:15078)
at r.unary (angular.js:15066)
at r.multiplicative (angular.js:15053)
at r.additive (angular.js:15044)
at relational (angular.js:15035)
at r.equality (angular.js:15026)
at r.logicalAND (angular.js:15018) "<b ng-bind-html="{{'general.help.notion.text3' | translate:{nbButton: vm.nbBtn} }}">"
Is there a way to use ng-bind-html with a parameter ?
Option 2 : Use translate directive
<p translate="myLabel" translate-values="{'param': vm.myParam}"> </p>
But what I get is for example : There is <b>2</b> value.
My current sanitize strategy for angular translate is escaped, I tried with sanitize but in french all my accent are converted into their html code, for example : Déroulement d'un chapitre
I also try the escapeParameters and sanitizeParameters strategies and always I get : There is <b>2</b> value.
Do you know how I can achieve that ?
Thanks in advance
Takeshi

Try something like this:
<p ng-bind-html="'myLabel' | translate"></p>
Remember to include $sce service.

You could use the $translate service in order to get the string translated in the controller (providing the param as parameter), then set the translated value to a var and bind (ng-bind-html) this var in the view.
Something like this (I did not use the controllerAs syntax for brevity):
controller js
$scope.message = "About to be translated..."
$translate('myLabel', {param: 1}).then(function (text) {
$scope.message = $sce.trustAsHtml(text);
}, function (textID) {
$scope.message = $sce.trustAsHtml(text);
});
view
<p ng-bind-html="message"></p>
Working Plunker
Remember to inject the $sce service.

Related

ngClass Directive: Can I use multiple expressions to add multiple classes?

Here is an example of what I want to achieve
data-ng-class="{ 'tooltip_show' : showTooltip , 'tooltip__' + brand.settings.name }"
but it doesn't work.
Use the array form for ng-class:
<div ng-class="[showTooltip ? 'tooltip_show' : '',
'tooltip__' + brand.settings.name]">
<div>
OR compute the class in JavaScript:
<div ng-class="computeClass(tooltip_show, brand.setting.name)">
</div>
$scope.computeClass(show, name) {
var obj = {};
obj.showTooltip = show;
obj['tooltip_'+name] = true;
return obj;
};
The later approach is more easily debugged and better for complex computation.
See also,
AngularJS ng-class Directive Reference - Known Issues
AngularJS Developer Guide - Why mixing interpolation and expressions is bad practice
It looks like you haven't set a value for the second item. Did you mean something like
{ 'tooltip_show' : showTooltip , 'tooltip__' + brand.settings.name : tooltipText }
or
{ 'tooltip_show' : showTooltip , 'tooltip__' : brand.settings.name }
?
http://jsbin.com/genaqapefe/edit?html,js,output
data-ng-class="{ 'tooltip_show': showToolTip, {{ 'tooltip_' + brand.settings.name }}: true }"
This is working for me in this bin. I couldn't get it to evaluate without the curly braces, although not sure if that's the best practice.

How do I do this in angular? I have a $scope.photos, but I want the h1 to show the category if it exists otherwise display "Explore"

In React, I would have just done something like
<h1>{this.props.photos ? this.props.photos.category : 'Explore'}</h1>
How can I achieve the same in angular?
When I try something like this in my controller, I get category is not defined.
$scope.photos.category = $scope.photos ? $scope.photos.category : 'Explore';
If $scope.photos is undefined, you cannot assign value to $scope.photos.category, for that photos need to be defined.
However if you want to show category you could do:
$scope.category = $scope.photos ? $scope.photos.category : 'Explore';
and then used:
<h1>{{category}}</h1>

How can I change a value inside of ng-repeat after the repeat complete?

I have a JSON which provides me a user's working experiences info. But country and city's are provided in a code format (TR,DE etc.)
I am using ng-repeat to pass them into html like this
<div ng-repeat="e in experiences">
<span>{{e.Name}}</span>
<span ng-init="changeCodeToFullName(e.Country)">{{vm.CountryFullName[$index]}}</span>
</div>
I am using ng-init to convert Country Code to full name. changeCodeToFullName is an angular service written by me, Is this a correct method? If it is, I can't access the dom to change CountryFullName value. I tried to access them in JS file like vm.CountryFullName[0]="TEST" but it didn't worked. I need to use e.Country variable after, therefore I can't change the original .e.Country value.
How can I access a variable inside of ng-repeat after ng-repeat completed?
How about using a custom filter:
<div ng-repeat="e in experiences">
<span>{{e.Name}}</span>
<span>{{e.Country | changeCodeToFullName}}</span>
</div>
angular.module('App').filter('changeCodeToFullName', function(YourService) {
return function(country) {
return YourService.getFullCountryName(country)
}
})
Here's an example: http://codepen.io/rustydev/pen/YWyqJB
This is one way of doing it - but this ngInit value won't be reparsed if the list updates. Why not just format the data in the JSON request response - such as:
$http.get("json.json").success(function(data) {
$scope.exeriences = data.map(function(obj) {
//Format results;
if (obj.Country == "DE") {
obj.Country = "Germany"; //etc
}
return obj;
});
});

Issue With name containing - in angular service

I have a service like below
var places = [
{ "city" : "Bangalore","country-name": "India"},
{ "city" : "Mysore","country-name": "India"}
];
this.getCities = function(){
return places;
};
I am calling the getCities in my controller and displaying the data in my html like below.
<li ng-repeat="place in places">
<label>City : {{place.city}}</label>
<label>Country : {{place.country-name}}</label>
</li>
But the country name is coming as 0 and the city is working fine.
Please find the plunker here
Please let me know why it is happening
Rename country-name to countryName. You can't have dashes in your property names and then access them with the dot operator.
If for some reason you're consuming an api that you don't control, you can do this instead:
<label>Country : {{place['country-name']}}</label>

How to do a logic operation in Angular Template

All:
I wonder how can I set a OR operator on a HTML string in Angualar Template, something like:
<div>{{value || <h6>No Header for now.</h6>}}</div>
The logic is if value is a string but not undefined, we show the value text, otherwise we show a error "No Header for Now" wrapped up by <h6>.
I do not know why this expression can not be correctly interpreted?
Thanks
This can be solved with ng-if:
<div ng-if="value">value</div>
<div ng-if="!value"><h6>No Header for now.</h6></div>
You can add specific attributes (e.g. class) and/or directives (e.g. ng-click) on each <div>.
The problem with using a single element is that you have to repeat your condition several times:
<div ng-class="{ value: 'class1', !value: 'class2' }"
ng-click="value ? action1() : action2()"
ng-bind-html="value || html">
</div>
You have to put a string, not an expression: <h6>No Header for now.</h6> is an invalid js expression. '<h6>No Header for now.</h6>' is a string and can be displayed in the {{ }}.
<div>{{value || '<h6>No Header for now.</h6>' }}</div>
or
<div>{{value != null ? value : '<h6>No Header for now.</h6>' }}</div>
I'm convinced the 2nd works.
EDIT:
If you want to add html code in the {{ }}, it is another problem. See AngularJS : Insert HTML into view, the filter 'sanitize' in 2nd answer should help you ( call {{ '<h1>test</h1>' | sanitize }} and it should work.
EDIT 2:
In a js file:
angular.module('yourapp')
.filter("sanitize", ['$sce', function($sce) {
return function(htmlCode){
return $sce.trustAsHtml(htmlCode);
}
}]);
In view:
<div>{{value || '<h6>No Header for now.</h6>' | sanitize }}</div>
In dont know if you need 'ngResource' to use $sce, if it doesn't work, you will have to install angular-resource :/

Resources