93

I have an AngularJS application, which collects data from input, transforms a model into a string using JSON.stringify() and lets a user edit this model in such a way that input fields get updated if the <textarea> element is updated and vice versa. Some kind of two-way binding :)

The problem is that the String itself looks ugly and I would like to format it so it looks like this:

enter image description here

And not like it looks now:

enter image description here

Any ideas how this can be accomplished? If you need some additional info - don't hesitate asking. Every answer is highly appreciated and answered immediately.

Thank you.

P.S. I guess this should be some kind of directive or a custom filter. Data itself SHOULD NOT be changed, only the output.

6
  • 1
    Can you try this - In the textarea, press enter and format the resultant string as desired. Then in your $watch (based on the answer to previous question) over the textarea model, can you do a console.log() and see what value you get in the string for the enter key - I think it's "/n" Commented Apr 1, 2014 at 12:29
  • 1
    Based on this, I can suggest how you can format the text Commented Apr 1, 2014 at 12:29
  • {"anchorPosition":"1", "difficulty":"1", "includeInSequence":"1", "questionCount":"1"} Commented Apr 1, 2014 at 12:35
  • Basically nothing changed after String got formated. Commented Apr 1, 2014 at 12:36
  • See answers below - do they help? Commented Apr 1, 2014 at 12:37

6 Answers 6

439
+200

Angular has a built-in filter for showing JSON

<pre>{{data | json}}</pre>

Note the use of the pre-tag to conserve whitespace and linebreaks

Demo:

angular.module('app', [])
  .controller('Ctrl', ['$scope',
    function($scope) {

      $scope.data = {
        a: 1,
        b: 2,
        c: {
          d: "3"
        },
      };

    }
  ]);
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="[email protected]" data-semver="1.2.15" src="//code.angularjs.org/1.2.15/angular.js"></script>
  </head>

  <body ng-controller="Ctrl">
    <pre>{{data | json}}</pre>
  </body>

</html>

There's also an angular.toJson method, but I haven't played around with that (Docs)

Sign up to request clarification or add additional context in comments.

7 Comments

Yes, I know this already. But I can't make this filter because the textarea itself is a model.
This is so simple, yet so useful :D
@ra170 Be so kind to read the whole question carefully, not just the heading. I was asking for a slightly different thing than a simple json filter.
Note that your <pre> tag shouldn't have white-space property set to normal or no-wrap. Otherwise, your JSON wouldn't be indented as you want.
I was having problems but I was doing without <pre>.... I saw this answer and I fixed .... thanks!!
|
67

You can use an optional parameter of JSON.stringify()

JSON.stringify(value[, replacer [, space]])

Parameters

  • value The value to convert to a JSON string.
  • replacer If a function, transforms values and properties encountered while stringifying; if an array, specifies the set of properties included in objects in the final string. A detailed description of the replacer function is provided in the javaScript guide article Using native JSON.
  • space Causes the resulting string to be pretty-printed.

For example:

JSON.stringify({a:1,b:2,c:{d:3, e:4}},null,"    ")

will give you following result:

"{
    "a": 1,
    "b": 2,
    "c": {
        "d": 3,
        "e": 4
    }
}"

3 Comments

note that this preserves the $$hashKey property angular uses for internal model tracking
You can also do JSON.stringify(object, null, 2) where 2 is the number of white space characters.
@ Lukasz, Can I avoid the $$Hashkey?
23

If you are looking to render JSON as HTML and it can be collapsed/opened, you can use this directive that I just made to render it nicely:

https://github.com/mohsen1/json-formatter/

enter image description here

Comments

11

In addition to the angular json filter already mentioned, there is also the angular toJson() function.

angular.toJson(obj, pretty);

The second param of this function lets you switch on pretty printing and set the number of spaces to use.

If set to true, the JSON output will contain newlines and whitespace. If set to an integer, the JSON output will contain that many spaces per indentation.

(default: 2)

2 Comments

my page is blocked when i give him a array of 1000 objects
Youvariable = angular.toJson ...., as you wrote, it looks like the result in pretty
6

I guess you want to use to edit the json text. Then you can use ivarni's way:

{{data | json}}
and add an adition attribute to make
 editable

<pre contenteditable="true">{{data | json}}</pre>

Hope this can help you.

Comments

2

If you want to format the JSON and also do some syntax highlighting, you can use the ng-prettyjson directive. See the npm package.

Here is how to use it: <pre pretty-json="jsonObject"></pre>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.