Angular translate - javascript

in my app I would like to add functionality to translate page into all languages that user has set in browser and if none of them is available translate into default english... Problem is browser inconsistency with language support. I found a workaround for this, I make a http call to some webservice which returns user languages. It is done in app.run
app.run(function($rootScope, UserDataService, $translate){
UserDataService.getUserBrowserLanguage().then(function(language){
var langArr = language.split(',').map(function(el){
return el.split(';')[0].split(/-|_/)[0];
});
$translate.fallbackLanguage(langArr)
$translate.preferredLanguage(langArr[0]);
$translate.use(langArr[0]);
});
});
and in app config:
app.config(function ($routeProvider, $translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: '/languages/',
suffix: '.json'
});
});
section because I can't make http call in config and it fails... :/ langauges are loaded but the translation isn't changed... What am I doing wrong? Here is plunker:
http://plnkr.co/edit/41SngK2tCTeaq8IhMbcM
it doesn't display anything no translations... why? :( I would be very pleased with any help.

As for your question the view doesn't show anything due to the following errors:
Few mistakes:
First of all, ng-app should be moved to the html tag.
<html ng-app="translateApp">
Second, if you use a variable from a controller you should use ng-controller.
<div ng-controller="mainCtrl">
Last, when you bind a variable from the view to the controller the variable should be on the $scope.
$scope.translation = $translate.instant('GENERAL');
Fixed your plunker with my comments: Plunker.
As for the way $translate works, I am not really familiar with this service but I will try and have a look.
EDIT:
I studied $translate service in order to give you a full answer including fixing the way you used Translate, So first of all I put a timeout of 2 seconds before trying to use translate.instant, the reason is that I am letting translate loading the JSON files in the config.
I have added 2 buttons so you could switch between the languages and see it is working.
Enjoy! Here is the updated working Plunker.
Here is translate documentation site I used.

Related

$anchorScrollProvider.disableAutoScrolling(): undefined is not a function

I’m using Angular 1.3.15. I’m trying to disable automatic scrolling when the hash changes.
According to the documentation I need to call disableAutoScrolling() on the $anchorScrollProvider. So here’s my code:
var app = angular.module("myApp", [
// ... dependencies here ...
]);
app.config(['$locationProvider', '$anchorScrollProvider', function($locationProvider, $anchorScrollProvider) {
$locationProvider.html5Mode({ enabled: true, requireBase: false });
$anchorScrollProvider.disableAutoScrolling();
}]);
This, however, throws an “undefined is not a function” error on the second to last line.
Any ideas why it’s happening?
Thanks.
Solution is The issue was rather embarrassing (this is the author of the question, BTW).
While looking for a way to disable auto scrolling, some people suggested that the only way to make it actually work was to remove $anchorScroll from the module.
So in one of my controllers I’d added .value($anchorScroll, angular.noop) and forgot about it. Obviously that removed $anchorScroll from my module hence the errors.
Thanks everyone for help. You guided me towards the solution.

Angular Js how to show dynamic content

I am completely new to ANgularJs. As part of one project my page should show some content dynamically is changes in database. This changed vale can be obtained by a http get.
Before I try the complete scenario, I just wanted to see if is working atleast locally by taking a local variable. But its not working please suggest me how do I handle this.
angular.module('MyApp') .controller('HomeCtrl', function HomeCtrl($scope, $alert, $auth,$location) {
Counter=10;
Counter=Counter+1;
$scope.user={};
$scope.user.counter=Counter;
}
HomeCtrl($scope,$alert,$auth,$location);
);
It looks like you need to remove the following line:
HomeCtrl($scope,$alert,$auth,$location);
As you are still in the controller function call
remove
HomeCtrl($scope,$alert,$auth,$location);
but there were some other things also wrong..
working version:
fiddle -- http://jsfiddle.net/beLbv6L1/

How to bind javascript and ng-click event in html element using angular js?

I am trying to bind the following json response in my html page.
The json is as follows:
{
"key":{
"text":"<p>For more information, please visit Support .</p>"
}
}
html page
<div ng-bind-html="message"></div>
Controller Code
$http({
method: 'GET',
url:'DAYS.json'
}).success(function(responsedata) {
$scope.message=responsedata.key.text;
}).error(function(responsedata){});
customizeWindow function inside controller
$scope.customizeWindow = function(url) {
window.open(url, "_blank", "toolbar=yes, scrollbars=yes, resizable=yes,top=70, left=190, width=970, height=460");
}
The ng-bind-html binds the html tags but it strips off the javascript and ng-click event.
i get only Support when i inspect element and the link does not work.
Please suggest me a solution.
This happens since angular Automatically uses $sce -> Strict Contextual Escaping. it allows you to ng-bind-html but it doesn't allow you to add possibly malicious code like JS.
What you are after is explicitly trusting that segment as HTML.
therefore:
angular.module('app', ["ngSanitize"]) // You have to include ngSanitize or it wouldn't work.
.controller('Ctrl', function ($scope, $sce){
$scope.htmlData = <p>For more information, please visit Support .</p> //Took from your example.
$scope.$watch("htmlData", function(newValue){
$scope.trustedData = $sce.trustAsHtml(newValuew);
});
});
HTML Usage:
<p ng-bind-html="trustedData"></p>
Angular Resource:
Strict Contextual Escaping (SCE) is a mode in which AngularJS requires
bindings in certain contexts to result in a value that is marked as
safe to use for that context. One example of such a context is binding
arbitrary html controlled by the user via ng-bind-html. We refer to
these contexts as privileged or SCE contexts.
As of version 1.2, Angular ships with SCE enabled by default.
read on : Angular on SCE - trustAsHtml method
ng-bind-html content is sanitized by default and its not meant to bring DOM into the page. You would use this method to bring content onto the page. Eg if you have a rich text editor - you want to feed it html content, however sanitized and thats when you use ng-bind-html.
For your purpose I would suggest to use templates or plain model binding.
Source of your json, what ever that is should not really know anything about the consumer side (your page) implementation/technology what if you move away from angularJS and start using Knockout, you will have to change server-side as well, because Knockout will have no idea about ng-click. Just pass back the content like http://www.google.com, 'For more information, please visit' and bind it.
{
"key":{
"textsource": {
source : 'http://www.google.com',
message : 'For more information, please visit '
}
}
}
<p>{{textsource.message}}<div ng-click="customizeWindow(textsource.source)\">Support</div> </p>
If you can't change server side, have a look at this example :
1) tell $sce your content is fine
$scope.message = $sce.trustAsHtml(json.key.text);
2) recompile your dynamicaly added content
$scope.init = function () {
var el = document.getElementById("dynamic");
$compile(el.childNodes[0])($scope);
};
NOTE: the recompile step is manual for now (press the recompile button). Follow this to make it work nicely.

Angular JS - How can I sanitize HTML in a controller?

I'm trying to sanitize HTML in the controller as I'm trying to update the document.title dynamically with the title of the post. (I know that for SEO purposes this isn't recommended but I need to use it here)
$scope.prevTitle = "dynamic title gets pulled in here &"
document.title = $scope.prevTitle
For this example, I've just used a random HTML entity. I've tried the parseAsHtml method from the official documentation but I'm having no luck. I tried the following:
document.title = $sce.parseAsHtml($scope.prevTitle)
But no luck. The documentation suggests it needs to be used within a function. Any suggestions on how I would acheive this?
A console log of the above ( console.log($sce.parseAsHtml($scope.prevTitle)) ) would return:
function (b,c){return e.getTrusted(a,d(b,c))}
$sanitize can be used as #acg pointed out. Alternatively, you can use it directly with the ng-bind-html directive where it automatically sanitizes the output variable before rendering the output.
The above point is not quite clear in the documentation, but there is a fairly extensive example in it with which you can play in pluncker.
Please also bear in mind that ngSanitize is an external module and you need to explicitly load angular-sanitize.js or include it in your js minification.
Use $sanitise and trustAsHtml instead
First of all inject 'ngSanitize' in your module
Now in your controller, just add
$scope.prevTitle = "dynamic title gets pulled in here &"
document.title = $sce.trustAsHtml($scope.prevTitle)
If you want to sanitize the html returned, I would think it would be as simple as using the $sanitize service:
document.title = $sanitize($sce.parseAsHtml($scope.prevTitle))

Stuck with Angular-UI TinyMce

I'm trying to use the Angular-UI TinyMCE directive in my Angular app.
What happens is, I query an endpoint, it returns an array of objects. I have a function that then converts that to a long string with HTML tags in it. Then that data is set to a $scope.tinymceModel
This all works fine. I can console.log($scope.tinymceModel) and its the proper data.
The problem is the HTML parse function needs to run after the endpoint query is returned. So I've called the function inside the .success() callback. For some reason when I set the $scope.tinymceModel inside of the callback the TinyMCE directive ignores it. Even if I make it $scope.tinymceModel = 'test' but if I place $scope.tinymceModel = 'test' outside of the callback it shows up in tinymce just fine.
This tells me that for some reason when the TinyMCE directive is loaded it needs the tinymceModel to already be populated with data. I'm not sure how I get around this.
This also tells me that I may have another problem after this. The next task with TinyMCE is the user can then edit the text, click a button and the app will send a POST with the updated info inside tinymceModel If this was a regular text box it would be simple because of the data-binding. However it seems TinyMCE doesn't play well with databinding.
Any ideas?
I've attempted to recreate what you're describing (substituting $http with $timeout) to no avail. Here's my solution and it seems to be working just fine.
HTML:
<div ng-controller="MainCtrl">
<textarea ui-tinymce="" class="form-control" ng-model="someHtml"></textarea>
</div>
JavaScript:
angular.module('testTinymceApp')
.controller('MainCtrl', function ($scope, $timeout) {
$timeout(function() {
$scope.someHtml = '<h1>HELLO THERE</h1>'
}, 7000);
// This does the same thing with an XHR request instead of timeout
// $http.get('/some/data/').success(function(result) {
// $scope.someHtml = '<h1>HELLO THERE</h1>'
// });
});
I thought maybe you could compare with your own application? I know for a fact that this works with XHR requests. I'm building a CMS at work that uses what I assume is an identical workflow.
The someHtml attribute in this snippet will also be valid HTML under the covers, so sending it back in a POST request should be extremely easy.
If this is not sufficient, please provide further explanation.
Figured it out!, the issue has to do with a bug in the TinyMCE Directive. By default there is no priority set. Setting it to a value of 1 or higher fixes it. It seems that the current version of Ui-TinyMCE Directive has this fixed, but the version I pulled down less than a month ago didn't have it fixed.

Categories