How do I handle newlines in JSON?

Viewed 737328

I've generated some JSON and I'm trying to pull it into an object in JavaScript. I keep getting errors. Here's what I have:

var data = '{"count" : 1, "stack" : "sometext\n\n"}';
var dataObj = eval('('+data+')');

This gives me an error:

unterminated string literal

With JSON.parse(data), I see similar error messages: "Unexpected token ↵" in Chrome, and "unterminated string literal" in Firefox and IE.

When I take out the \n after sometext the error goes away in both cases. I can't seem to figure out why the \n makes eval and JSON.parse fail.

10 Answers

This is what you want:

var data = '{"count" : 1, "stack" : "sometext\\n\\n"}';

You need to escape the \ in your string (turning it into a double-\), otherwise it will become a newline in the JSON source, not the JSON data.

TLDR: A solution to the author's problem.

Use String.raw literal:

var data = String.raw`{"count" : 1, "stack" : "sometext\n\n"}`;

For some reason all answers inside here focus on how to parse a JSON string representation in JavaScript, which may cause confusion regarding how to represent newlines on actual JSON. The latter is not language-dependent.

Strictly based on the question title :

How do I handle newlines in JSON?

Let's say you parse a JSON file using the following code in node (it could be any language though):


let obj = JSON.parse(fs.readFileSync('file.json'));
console.log(obj.mykey)

Below is the output for each of the possible contents of file.json:

Input 1:

{
  "mykey": "my multiline
   value"
}

Output 1:

SyntaxError: Unexpected token

Input 2:

{
  "mykey": "my multiline\nvalue"
}

Output 2:

my multiline
value

Input 3:

{
  "mykey": "my multiline\\nvalue"
}

Output 3:

my multiline\nvalue

Conclusion 1:

To represent a newline inside a json file we should use the \n character. To represent the \n we should use \\n.


How would we define each of the above inputs using JavaScript (instead of input file):

When we need to define a string containing JSON in JavaScript, things change a bit because of the special meaning that \n has also for JavaScript. But also notice how String.raw literal fixes this.

Input1:

let input1 = '{"mykey": "my multiline\nvalue"}'

//OR
let input1 = `{
  "mykey": "my multiline
   value"
}`;
//(or even)
let input1 = `{
  "mykey": "my multiline\nvalue"
}`;

//OR
let input1 = String.raw`{
  "mykey": "my multiline
   value"
}`;

console.log(JSON.parse(input1).mykey);

//SyntaxError: Unexpected token
//in JSON at position [..]

Input 2:

let input2 = '{"mykey": "my multiline\\nvalue"}'

//OR
let input2 = `{
  "mykey": "my multiline\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input2 = String.raw`{
  "mykey": "my multiline\nvalue"
}`;

console.log(JSON.parse(input2).mykey);

//my multiline
//value

Input 3:

let input3 = '{"mykey": "my multiline\\\\nvalue"}'

//OR
let input3 = `{
  "mykey": "my multiline\\\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input3 = String.raw`{
  "mykey": "my multiline\\nvalue"
}`;

console.log(JSON.parse(input3).mykey);

//my multiline\nvalue

Conclusion 2:

To define a json string in javascript the easiest way would be to use String.raw, because it does not require any escaping (Well apart from backtick which is escaped like this String.raw`abc${"`"}def` ).

Of course, the easiest way to create json in javascript, in general, is to convert a javascript object to json (using JSON.stringify).

well, it is not really necessary to create a function for this when it can be done simply with 1 CSS class.

just wrap your text around this class and see the magic :D

 <p style={{whiteSpace: 'pre-line'}}>my json text goes here \n\n</p>

note: because you will always present your text in frontend with HTML you can add the style={{whiteSpace: 'pre-line'}} to any tag, not just the p tag.

You might want to look into this C# function to escape the string:

http://www.aspcode.net/C-encode-a-string-for-JSON-JavaScript.aspx

public static string Enquote(string s)  
{ 
    if (s == null || s.Length == 0)  
    { 
        return "\"\""; 
    } 
    char         c; 
    int          i; 
    int          len = s.Length; 
    StringBuilder sb = new StringBuilder(len + 4); 
    string       t; 

    sb.Append('"'); 
    for (i = 0; i < len; i += 1)  
    { 
        c = s[i]; 
        if ((c == '\\') || (c == '"') || (c == '>')) 
        { 
            sb.Append('\\'); 
            sb.Append(c); 
        } 
        else if (c == '\b') 
            sb.Append("\\b"); 
        else if (c == '\t') 
            sb.Append("\\t"); 
        else if (c == '\n') 
            sb.Append("\\n"); 
        else if (c == '\f') 
            sb.Append("\\f"); 
        else if (c == '\r') 
            sb.Append("\\r"); 
        else 
        { 
            if (c < ' ')  
            { 
                //t = "000" + Integer.toHexString(c); 
                string t = new string(c,1); 
                t = "000" + int.Parse(tmp,System.Globalization.NumberStyles.HexNumber); 
                sb.Append("\\u" + t.Substring(t.Length - 4)); 
            }  
            else  
            { 
                sb.Append(c); 
            } 
        } 
    } 
    sb.Append('"'); 
    return sb.ToString(); 
} 

As I understand you question, it is not about parsing JSON because you can copy-paste your JSON into your code directly - so if this is the case then just copy your JSON direct to dataObj variable without wrapping it with single quotes (tip: eval==evil)

var dataObj = {"count" : 1, "stack" : "sometext\n\n"};

console.log(dataObj);

Related