Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Pretty print JSON without overkill

I'm using the below code to display an unauthorized message in JSON:

def render_unauthorized
  # Displays the Unauthorized message since the user did
  # not pass proper authentication parameters.
  self.headers['WWW-Authenticate'] = 'Token realm="API"'
  render json: { 
    error: { 
      type: "unauthorized",
      message: "This page cannot be accessed without a valid API key." 
      } 
    }, status: 401
end

Which outputs:

{"error":{"type":"unauthorized","message":"This page cannot be accessed without a valid API key."}}

So my question is this: Is there a way to pretty print this message (WITHOUT putting it in a separate view and using some 3rd party gem).

Edit: What is pretty print?

Properly spaced, and well .. pretty. Here's the output I'd like to see:

{
  "error": {
    "type": "unauthorized",
    "message": "This page cannot be accessed without a valid API key." 
  }
}

Solution

Using @emaillenin's answer below worked. For the record, here's what the final code looks like (since he hadn't included the whole thing):

def render_unauthorized
  # Displays the Unauthorized message since the user did
  # not pass proper authentication parameters.
  self.headers['WWW-Authenticate'] = 'Token realm="API"'
  render json: JSON.pretty_generate({ # <-- Here it is :')
    error: { 
      type: "unauthorized",
      message: "This page cannot be accessed without a valid API key." 
      } 
    }), status: 401
end
like image 356
FloatingRock Avatar asked Jul 27 '14 16:07

FloatingRock


2 Answers

Use this helper method built into JSON.

JSON.pretty_generate

I just tried and it works:

> str = '{"error":{"type":"unauthorized","message":"This page cannot be accessed without a valid API key."}}'
> JSON.pretty_generate(JSON.parse(str))
 => "{\n  \"error\": {\n    \"type\": \"unauthorized\",\n    \"message\": \"This page cannot be accessed without a valid API key.\"\n  }\n}"
like image 176
Lenin Raj Rajasekaran Avatar answered Oct 14 '22 06:10

Lenin Raj Rajasekaran


If you (like I) find that the pretty_generate option built into Ruby's JSON library is not "pretty" enough, I recommend my own NeatJSON gem for your formatting.

To use it gem install neatjson and then use JSON.neat_generate instead of JSON.pretty_generate.

Like Ruby's pp it will keep objects and arrays on one line when they fit, but wrap to multiple as needed. For example:

{
  "navigation.createroute.poi":[
    {"text":"Lay in a course to the Hilton","params":{"poi":"Hilton"}},
    {"text":"Take me to the airport","params":{"poi":"airport"}},
    {"text":"Let's go to IHOP","params":{"poi":"IHOP"}},
    {"text":"Show me how to get to The Med","params":{"poi":"The Med"}},
    {"text":"Create a route to Arby's","params":{"poi":"Arby's"}},
    {
      "text":"Go to the Hilton by the Airport",
      "params":{"poi":"Hilton","location":"Airport"}
    },
    {
      "text":"Take me to the Fry's in Fresno",
      "params":{"poi":"Fry's","location":"Fresno"}
    }
  ],
  "navigation.eta":[
    {"text":"When will we get there?"},
    {"text":"When will I arrive?"},
    {"text":"What time will I get to the destination?"},
    {"text":"What time will I reach the destination?"},
    {"text":"What time will it be when I arrive?"}
  ]
}

It also supports a variety of formatting options to further customize your output. For example, how many spaces before/after colons? Before/after commas? Inside the brackets of arrays and objects? Do you want to sort the keys of your object? Do you want the colons to all be lined up?

Using the aligned option would allow your output to look like this:

{
  "error": {
    "type"    : "unauthorized",
    "message" : "This page cannot be accessed without a valid API key." 
  }
}
like image 23
Phrogz Avatar answered Oct 14 '22 07:10

Phrogz