Rendering unicode-utf-8 turkish characters with angular-js - javascript

Characters from a binded JSON text, Turkish the letters are shown with wrong encoding for eg. Özlem Güzelharcan which shall look like "özlem güzelharcan". I added <meta characters="utf-8"> in the head still no solution and there was no problem with laravel blade views.
If necessary this is how I get and use data:
view:
<div class="comment" ng-hide="loading" ng-repeat="comment in comments">
Comment #{{ comment.id }} </h3> <p>{{comment.title}}</p>
{{comment.author_id}} / {{comment.author.name}}
Services:
// public/js/services/commentService.js
angular.module('commentService', [])
.factory('Comment', function($http) {
var data = {
// get all the comments
get : function() {
return $http.get('/api/comments/');
}
}
console.log(data);
return data;
});
//controller (shortly)
.controller('mainController', function($scope, $http, Comment) {
// object to hold all the data for the new comment form
$scope.commentData = {};
// loading variable to show the spinning loading icon
$scope.loading = true;
// get all the comments first and bind it to the $scope.comments object
// use the function we created in our service
// GET ALL COMMENTS ====================================================
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
});
Which method is used to clean characters with AngularJS?
Thanks

Eventually, after trying many things, I discovered that you have to use ng-bind-html or ng-bind-html-unsafe (with ngSanitize) to get the correct encoding. Here is how it works in my view:
Comment #<span ng-bind-template="{{comment.id}}"></span> </h3>
<span ng-bind-html="comment.title "></span>
<p><div ng-bind-html="comment.content | truncate:25"></div></p>

Related

Evaluate or call directive on click in angular

I am trying to load an image from json and if image is not available, then show firstname and lastname.
I have controller like this:
app.controller('task1Controller',['$scope', 'taskFactory', '$state', 'imageTestService', function($scope, taskFactory, $state, imageTestService){
$scope.taskData = {};
$scope.current = 0;
taskFactory.get().then(function(response){
$scope.jsonData = response.data.data.resultCareGivers;
});
$scope.back = function(){
$scope.current = ($scope.current !== 0 ? $scope.current - 1 : 0);
};
$scope.next = function(){
$scope.current = ($scope.current !== $scope.jsonData.length-1 ? $scope.current + 1 : $scope.jsonData.length-1);
};
}]);
and a Directive to verify image loading:
app.directive('imageTestDirective', function($http){
return {
restrict: 'A',
link: function($scope, elem, attrs){
attrs.$observe('ngSrc', function(ngSrc){
if(ngSrc != null && ngSrc != ""){
$http.get(ngSrc).then(function(success){
$scope.noImage = false;
console.log('success loading image', success);
}, function(error){
$scope.noImage = true;
console.log('error loading image', error);
});
}
});
}
};
});
Html with attribute directive and next and back button to cycle through json:
<img image-test-directive ng-show="noImage === false" ng-src="{{jsonData[current].profilepic}}" alt=""/>
<div ng-if="noImage">
<div>{{jsonData[current].firstName.charAt(1)+jsonData[current].lastName.charAt(1)}}</div>
</div>
<div class="col-xs-12">
<div class="col-xs-2">
<button type="button" ng-click="back()">Back</button>
</div>
<div class="col-xs-6" style="text-align: right">
<button type="button" ng-click="next()">Next</button>
</div>
</div>
The problem is the directive works on page load and the image is loaded properly, but I when I navigate through json object to view details, the directive is not evaluated (I mean when there no image inside json, it should show firstName+lastName)
How do I achieve it?
I think you wrote the logic too complicated for this use case.
In basic words JSON you get from Server contains some data with/without image URL or with broken image URL.
So instead to make HTML to be complicated, just embed your JSON in service and bring new JSON to your controller.
for example:
app.service('SomeService',['$q', /* ... */ function ($q /* ... */) {
function MyNewJSON(origJSON){
// check here if origJSON contains wrong image url
// and set new JSON key hasImage = true or false by validating it here in service and not in directive.
this.hasImage = true;
/* ... */
}
function getNewJSON(){
return new MyNewJSON(origJSON); // it might be promise and you need resolve it in controller
}
}]);
So your HTML should look like:
<img ng-if="stateData.hasImage" ng-src="stateData.profilepic" alt=""/>
<div ng-if="!stateData.hasImage">
<div >{{stateData.firstName.charAt(1)+stateData.lastName.charAt(1)}}</div>
</div>
No directive needed.
Since image validation can take some time, you can put default image (some kind of placeholder)

How to display a returned json in angular view?

I am implementing a search in the github repository.
I need to display the information that i get from here: https://api.github.com/search/repositories?q=bootstrap . for instance into a view or HTML
<div ng-app="newsearchApp">
<div ng-controller="MainCtrl">
<form action="#/about" method="get">
<input ng-model="searchText" />
<button ng-click="search()">Search</button>
</form>
</div>
</div>
the code for searching the Github repository;
angular.module('newsearchApp')
.controller("MainCtrl", ["$scope", function($scope) {
$scope.searchText = "";
$scope.search = function() {
console.log($scope.searchText);
var item = $scope.searchText;
// console.log(item)
var GithubSearcher = require('github-search-api');
var github = new GithubSearcher({username: 'test#something.com', password: 'passwordHere'});
var params = {
'term': $scope.searchText
};
//i am not certain about the 'userData'
github.searchRepos(params, function(data) {
console.log(data);
$scope.userData = data; //i am not certain about the 'repoData'
});
} }]);
the problem is here, when populating the json object to HTML
<div ng-repeat="repo in userData | filter:searchText | orderBy:predicate:reverse" class="list-group-item ">
<div class="row">
<div class="col-md-8">
<h4>
<small>
<span ng-if="repo.fork" class="octicon octicon-repo-forked"></span>
<span ng-if="!repo.fork" class="octicon octicon-repo"></span>
<small>{{repo.forks_count}}</small>
</small>
<a href="{{repo.html_url}}" target="_blank" >
{{repo.name}}
</a>
<small>{{repo.description}}</small>
<small>{{repo.stargazers_count}}</small>
<a href="{{repo.open_issues_count}}" target="_blank" >
Open Issues
</a>
<small>{{}}</small>
</h4>
</div>
</div>
</div>
the results are null on the HTML but are not null on the console.
thanks in advance
the results are null
The problem is, that Angular doesn't notice that the GitHub server has answered and doesn't update the view. You have to tell Angular manually to re-render the view. Try calling $scope.$apply():
github.searchRepos(params, function(data) {
console.log(data);
$scope.userData = data;
$scope.$apply();
});
If you'd make your request to the GitHub API with Angulars $http service, then this would not be needed - you'll only need $scope.$apply() if something asynchronous happens which doesnt live in the "Angular world" - for example things like setTimeout, jQuery ajax calls, and so on. That's why there are Angular wrappers like $timeout and $http.
More details: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
The GitHub API can be accessed using the AngularJS $http service:
app.controller("myVm", function($scope,$http) {
var vm = $scope;
var url = "https://api.github.com/search/repositories?q=bootstrap"
$http.get(url).then(function onSuccess(response) {
vm.data = response.data;
console.log(vm.data);
})
})
HTML
<div ng-app="myApp" ng-controller="myVm">
<div ng-repeat="item in data.items">
{{item.full_name}}
</div>
</div>
The DEMO on JSFiddle
Since you're not using the Angular $http service, angular is not aware of the changes. You need to manually tell Angular to re-render and evaluate by using
$scope.$apply();

Angulrjs: A controller doesn't send a value via a factory with the "as" statement

I've been teaching myself how to use the as statement of Angularjs's controller, but struggling to make controllers communicate with others, using the as syntax.
<script type="text/javascript">
angular.module('angularApp', [])
.factory('MessageService', function(){
var message = {
addedItem: "initialMessge"
};
return {
returnMessage: message//This is supposed to be the "var message" defined above
};
})
.controller('DiaplayingProductController', function(MessageService){
var instance = this;
this.data = {
message: MessageService.returnMessage.addedItem
};
})
.controller('ProductController', function($scope, $http, MessageService) {
var instance = this;
this.data = {
message: MessageService.message,
//There are other stuff here
};
this.addItem = function(productName) {
$http({
//other tasks
}).then(function addSucces(response) {
instance.data.message.addedItem = productName;
});
};
});
<span ng-controller="DiaplayingProductController as dpc" ng-bind="dpc.data.message"></span>
<div ng-controller="ProductController as pc">
#foreach ($products as $index => $product)
<div class="product">
<button ng-click="pc.addItem({{$product->name}})>
Add it to Cart
</button>
</div>
#endforeach
</div>
I use Laravel, so {{$product->name}} and #foreach are Laravel's expression.
In a nutshell,
There are one <span> and multiple <button>s, based on the result of #foreach (Again, I use Laravel, so this is basically the same thing as php's foreach)
When one of the <button> is pressed, the content of <span> is supposed to be updated.
The event is triggered in ProductController, which is supposed to update message of DiaplayingProductController, via MessageService.
The message is not going to be sent to the span tag.
This question may be silly. However, there are not many information resources out there which deal with this as statements, so I'd like to ask some advice here. Thank you in advance!
What's this #foreach?
There's a coma in your attributes. Shouldn't be there.
The expression in your ng-click has a missing parenthesis. Also, it should be an expression, therefore the {{}} have nothing to do here.
The data object are not shared between the controllers. You should:
use directives and pass the data using attributes ('=').
set the data in the $scope, which is not as good a solution
use a service as an intermediary (each controller can set/get the value
from that service)

Can't get the datas in angularJs

I have html page like
<div ng-controller="userListControl">
...
</div>
<div ng-controller="userDetailsControl">
....
</div>
And i have angular Js code is
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", ['$scope','$http', function($scope, $http)
{
$http.get('data/userData.json').success (function(data){
$scope.users = data;
$scope.users.doClick = function(user,event) {
userInfo(user);
}
});
}]);
function userInfo(users)
{
console.log(user);
userDirectory.controller("userDetailsControl", function($scope)
{
console.log('well')
$scope.user = users;
console.log($scope.user)
});
}
Here Everything is working fine. But when we are calling click event, That userInfo called with particular Data. But Second controller gives an error(angular js Error).
I am new one in angular jS. I dont know this logic is correct or not.
I have list items in first Controller. When we are clicking on list, It gets data from particular list and passed to another design. That design have detailed data. So the 2nd controller shows particular list detailed Section
First, There is no need to declare your controller inside a function - I don't think that you're trying to lazy-load controllers. Make it available to your app when it starts.
Second, you need to pass data to the userDetailsControl controller. There are various ways to do this, but here you could just use the $rootScope.
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", function($scope, $rootScope, $http)
{
$scope.selectUser = function(user){
$rootScope.selectedUser = user;
}
$http.get('data/userData.json')
.success (function(data){
$scope.users = data;
});
})
.controller("userDetailsControl", function($scope, $rootScope){
$rootScope.$watch("selectedUser", function(newVal){
$scope.user = newVal;
}
}
and in your HTML:
<div ng-controller="userListControl">
<button ng-repeat="user in users" ng-click="selectUser(user)">{{user.name}}</button>
</div>
<div ng-controller="userDetailsControl">
<div>{{user.name}}</div>
<div>{{user.otherDetails}}</div>
</div>

$watch got unexpected multiple events in AngularJS?

I am trying to use AngularJS and moment.js in-order to format time after the json data loaded, and I used $watch to monitor the $scope.comments, but not sure why the $watch recognized 3 events (the result set from json contains 3 items) instead of 1-time as I expected. The console.lof('changed') has been executed 3 tiem
var MyApp = angular.module('MyApp', ['ng', 'commentController']);
MyApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('', {
templateUrl: '/partials/comment-list.html',
controller: 'CommentListCtrl'
});
}
]);
MyApp.directive("timeago", function () {
return function ($scope, element, attrs) {
$scope.$watch("comments", function () {
$('.timeago').each(function (index) {
console.log('chaneged');
$(this).removeClass('timeago');
var time = moment($(this).text());
//console.log(time.fromNow());
$(this).text(time.fromNow());
})
});
};
});
/* Controllers */
var commentController = angular.module('commentController', []);
commentController.controller('CommentListCtrl', function CommentListCtrl($http, $scope) {
$scope.comments = [];
$http.get('/api/json?n=3').success(function (data) {
$scope.commentsLoaded(data);
});
$scope.commentsLoaded = function (data, status) {
$scope.comments = data;
}
});
and the template:
<div ng-Controller="CommentListCtrl">
<ul class="comments" timeago>
<li ng-repeat="comment in comments">
<span class="timeago">{{comment.time}}</span>
<p>{{comment.content}}</p>
</li>
</ul>
</div>
Thank you very much for any help.
In your case, the reason $watch executes 3 times is:
The first time it executes is on startup, where newValue == undefined
The second time is when you call this line: $scope.comments = [];
The third time is when the json is received: $scope.comments = data;
It has nothing to do with your json has 3 items.
however, not sure why the console.log($(this).text()); after the data
loaded only get this : {{comment.time}} It seems that the event was
catched before the template rendered
Because at the time, angular does not update its bindings yet and the view is not updated.
For separations of concern and how we should work with mvc structure like angular, view is for displaying, you should not access data from there, access it though model instead. In your case, you're trying to format the display, it should be the job of a filter
Write a filter like this:
angular.module('commentController').
filter('dateFormat', function() {
return function(input) {
return moment(input).fromNow();
}
});
Use it in HTML, don't need timeago directive:
<div ng-Controller="CommentListCtrl">
<ul class="comments">
<li ng-repeat="comment in comments">
<span class="timeago">{{comment.time | dateFormat }}</span>
<p>{{comment.content}}</p>
</li>
</ul>
</div>
The watch method takes a function with 2 arguments (newValue,oldValue). You can check these values when the watch is executed.
$scope.$watch("comments", function (newValue,oldValue) {
From what i can tell, the first time it executes is on setup, where oldValue is null. Then on any other assignment. Check the values and you would know.
To handle it correctly put checks like
if(newValue && newValue!=oldValue) {
//do something
}

Categories

Resources