How can I use this json pretty print [ http://jsfiddle.net/KJQ9K/ ] with angularJS?
Lets assume myJsonValue is
{a:1, 'b':'foo', c:[false,'false',null, 'null', {d:{e:1.3e5,f:'1.3e5'}}]}
I want to be able to use below to render pre (as shown in example)
Angular already has the json filter built-in:
<pre>
{{data | json}}
</pre>
The json after the pipe | is an Angular Filter. You can make your own custom filter if you like:
app.filter('prettyJSON', function () {
function prettyPrintJson(json) {
return JSON ? JSON.stringify(json, null, ' ') : 'your browser doesnt support JSON so cant pretty print';
}
return prettyPrintJson;
});
To use your custom prettyJSON filter:
<pre>
{{data | prettyJSON}}
</pre>
ES6 version from #TeChn4K:
app.filter("prettyJSON", () => json => JSON.stringify(json, null, " "))
Another option is to turn the function into a filter...
app.filter('prettify', function () {
function syntaxHighlight(json) {
// ...
}
return syntaxHighlight;
});
HTML...
<pre ng-bind-html="json | prettify"></pre>
JsFiddle: http://jsfiddle.net/KSTe8/
A simpler code:
app.filter('prettyJSON', function () {
return function(json) { return angular.toJson(json, true); }
});
Remember to use the <pre> tag
You have a few options. What I consider the most "AngularJS" way is to wrap your custom object into an Angular service:
myAngularModule.service('myPrettyPrintService', ,myObject );
The inject that into a controller:
myAngularModule.controller('myTestController', function(myPrettyPrintService){}
Then inside the controller, reference the functions and sort:
myPrettyPrintService.syntaxHighlight();
Since anything defined in JavaScript, is global anyway you could technically just access it inside a controller:
syntaxHighlight();
That may screw up with unit testingt because it adds a external, undefined, dependency to your controller.
Related
If I have a filter defined
app.filter('filterName', function() {
return function(var) {
// Some filter stuff
}
}
I can invoke it on controller doing $filter('filterName')($scope.someObj);.
But, here is my question, if I have a function that use as a filter
$scope.myFilterFunction = function() {
return true;
}
In my HTML
<p ng-repeat="item in items | filter:myFilterFunction">{{item}}</p>
How can I use this function filter in the controller (I have tested with $filter but throws an error).
Thanks in advance.
If you already implement the custom filter filterName, why not use it?
Try
<p ng-repeat="item in items | filterName">{{item}}</p>
Updated
You just missing the parentheses.
<p ng-repeat="item in items | filter:myFilterFunction()">{{item}}</p>
Inject $filter in the controller and use it with your filter name.
controller.$inject = ['$filter'];
function controller($filter){
// code here
$filter('filterName')(arg1,arg2);
//
}
I have a JSON filter in view
<div ng-repeat="(key, value) in TData.Files
| map: toLocaleDate
| groupBy: 'da'">
<div><strong>{ Date:</strong> "{{ key }}" , Count: {{value.length}} } ,</div>
using a filter in controller
$scope.toLocaleDate = function (e) {
var date = e.da.split(" ");
e.da = date[0];
return e;
};
Now i Want to Have the Filtered Data into Another JSON Object. So i need to do th e filter in controller rather than in View .. How to implement that?
The expected result is like
[{'Date':"2012-01-12", Count:5},{'Date':"2012-01-13", Count:8}, ....]
As there is no default filter groupBy in angularjs So You have to make a filter for that
and you can use any filter in the controller just explained as
Inject the $filter dependency and in controller just use the simple syntax
$filter('filtername')('arraydata', 'other arguments');
http://jsfiddle.net/R8YZh/35/
If you need that in js code. You can use an injected method of angular-filter lib. The Filter "group by" is a part of this library. Use it like this.
function controller($scope, $http, groupByFilter) {
var groupedData = groupByFilter(originalArray, 'groupPropName');
}
https://github.com/a8m/angular-filter/wiki/Common-Questions#inject-filters
Angular $sce service seems to be encoding characters and not trusting the html. Is there an option to have the html trusted?
$scope.text = $sce.trustAsHtml('it's broken')
An example.
<p>it's working</p>
<p>{{ text }}</p>
Looks like.
it's working
it's broken
I'd rather not use ng-bind-html because it's meant to be used in a filter like the following.
{{ text | render }}
It is not the $sce that encode your html, actually nothing does that.
But when you use an interpolation {{ text }}, angular will detect that and replace it with a correct value via textNode.nodeValue, not something like innerHTML. Therefore, your ' will be treated as a normal text, not an encoded HTML entity.
That's why the ng-bind-html exists, and nothing prevent you from using the filter inside the ng-bind-html expression.
<div ng-bind-html="text | render | trustAsHtml"></div>
Example filters:
.filter('render', function () {
return function (value) {
return value + '!';
};
})
.filter('trustAsHtml', function ($sce) {
return function (value) {
return $sce.trustAsHtml(value);
};
})
Example Plunker: http://plnkr.co/edit/F8OQvoSzOR06TPepc2Fo?p=preview
I'm using this directive (wallop-slider-angularjs) and it requires an array of image urls, but my urls are properties of an array of objects. How can I bind the property in such a way that it is acceptable to the directive?
<div ng-repeat="user in users">
<wallop-slider
data-images="??user.media.mediumURL??"
data-animation="rotate"
data-current-item-index="currentSliderIndex"></wallop-slider>
</div>
media = [{'mediumURL':'http://whatever.com/image.jpg'},{'mediumURL':'http://whatever.com/image2.jpg'}]
I solved this with a custom filter:
app.filter('extractProperty', function() {
return function(array, propertyName) {
return array.map(function(item) { return item[propertyName]; });
};
});
To get an array containing the specific property you must use it like that:
<div ng-repeat="user in users">
<wallop-slider data-images="{{ media | extractProperty:'mediumURL' }}"...></wallop-slider>
</div>
Here is a working example:
http://plnkr.co/edit/WpuOCU?p=preview
Just create a function on the scope which will extract the needed properties from the array. Something like:
scope.getMediumUrls = function(arr) {
return $.map(arr, function(item) { return item.mediumURL; });
}
And then use it on the directive:
<div ng-repeat="user in users">
<wallop-slider data-images="getMediumUrls(user.media)"...></wallop-slider>
</div>
You need to loop through the object along with the key and corresponding properties.
Suppose you have JS object as
var media = [
{'mediumURL':'http://whatever.com/image.jpg'},
{'mediumURL':'http://whatever.com/image2.jpg'}
];
Lets apply for in loop for getting values
for(key in media){
alert(media[key].mediumURL);
}
Here "key" refers to index for media[] and "mediumURL" is the individual corresponding property.
In your case,
<div ng-repeat="user in users">
<wallop-slider
data-images="??user.mediumURL??"
data-animation="rotate"
data-current-item-index="currentSliderIndex"></wallop-slider>
</div>
Note: You were using "user.media.mediumURL", hence it wont work because "media" is not property for each object structure under media[].
You can refer to this link for more details on ng-repeat looping examples.
Edit: If you already have a dependency on jQuery, I would pick Shay Friedmans answer.
I think this will do your trick (without the need for any additional libraries).
// Helper function to pluck the url property from the media items.
function pluckUrls() {
var ret = [], c = $scope.mediaItems.length;
while(c--) {
ret.push($scope.mediaItems[c].url);
}
return ret;
}
// Function that is called each watch cycle. The return value will differ
// if one of the urls has been modified.
function getUniqueWatchValue() {
return pluckUrls().join();
}
// Function that is called whenever one of the urls has been modified.
function watchValueChanged() {
console.log('One of the urls has been modified');
$scope.mediaUrls = pluckUrls();
}
// Hook up the watch.
$scope.$watch(getUniqueWatchValue, watchValueChanged);
Plunker in action can be found here.
Note: I noticed a piece of code in that wallop-slider thingy that is watching a reference to the array, not it contents. I haven't tested it but it probably requires you to recreate the array completely instead of simply adding or removing element from it.
$scope.$watch('images', function(images) {
if (images.length) {
_goTo(0);
}
});
The easiest way to do is using underscore like the following:
<wallop-slider
data-images="_.pluck(user.media.mediumURL, 'mediumURL')"
data-animation="rotate"
data-current-item-index="currentSliderIndex"></wallop-slider>
</div>
But before that you need do 2 things:
add underscore
<script src="/whatever/underscore.js"></script>
inject underscorejs into controller like the folloiwng
angular.module('app', [])
.controller('Ctrl', function($scope, $window) {
$scope._ = $window._
});
Hope that help,
Ron
How can I check if an angular model is an array or an object? Is there a built in or do I have to write a filter isArray with Array.isArray()
{{[] | isArray}} doesn't work
You can use the angular.isArray function. It's built-in inside Angularjs.
If you want to use this function inside your template, you have to create a custom filter: http://docs.angularjs.org/tutorial/step_09
Example of what you want:
angular.module('...', []).filter('isArray', function() {
return function (input) {
return angular.isArray(input);
};
});
Then you can use the filter inside your template:
{{ myVar | isArray }}
I guess you can also add underscore/lodash to the rootScope and use it:
_ = require('lodash')
angular.module('app',[])
.run(function($rootScope){
$rootScope._ = _
})
And in the template:
<div ng-show="$root._.isArray(foo)">
<label> First element of Foo </label>
<span> {{ $root._.first(foo) }} </span>
</div>
The benefits - you have to add lodash only in one place, and it will be available everywhere. You can use many other things the same way, like Math functions for example. Just be reasonable and don't put too much javascript into expressions.