How to display multiline json text on a page?

Hello,

This might be simple, but as a newbie to JS/mobile app developing world, having a hard time to figure out how to display large text onto a ionic page with new lines.

I have contenseperated new line with \n
jsontext = ‘{“lyrics_en”: “Amazing grace! How sweet the sound \n That saved a wretch like me!”}’;
results = ;
song : any;

this.song = JSON.parse(this.jsontext);
this.results.push(this.song);

on html, doing something like this:

    <div *ngFor="let s of results">
     {{s.lyrics_en}}
    </div>

image

But on the console, I can see new line character inserted
image

Am I missing something here ? Why isnt the ‘That saved a wretch like me’ displayed in second line ?

If you have any best practices of handling multiline text (e.g. song lyrics) and displaying them, please let me know.

Appreciate your help. Thanks for your time!

Ionic seems not to make use of the new line command included in your json string.

A simple solution would be to split the lyrics string via split() into an array. So you would push the array from split to song variable and push that array to results. In your HTML template, add an inner *ngFor to output the lines and wrap them with a div or br.

Should work i think.

1 Like

You should use a pipe to transform your text:

{{s.lyrics_en | prettyPrint}}

and the pipe something like:

@Pipe({
  name: 'prettyPrint'
})
@Injectable()
export class PrettyPrint {

    transform(str: string) {
        return str.replace(/(?:\r\n|\r|\n)/g, '<br />');
    }

}
1 Like

You could also do something like this

nl2br(text: string) {
	return text.replace(/(\r\n|\n\r|\r|\n)/gm, "<br>");
}

Example

nl2br("test\rtest\r\ntest\n"); // "test<br>test<br>test<br>"

If you simply want linebreaks in there. With @gregg’s idea to split() the text, you could still use that function. Then you’d have 1 thing to split with, and not several differen’t variations of \r, \n etc.

nl2br("test\rtest\r\ntest\n").split("<br>"); // ["test", "test", "test", ""]

Just strip the empty ones, then go through them and wrap them in a <p>, that might be neater :slight_smile:

Quick edit: What @imediasolutions said is a great idea, where you could also do the paragraph approach. Whichever you prefer.

Edit: Full pipe example

@Pipe({
	name: 'prettyPrint'
})
@Injectable()
export class PrettyPrint {

    transform(str: string) {
        let replaced = str.replace(/(\r\n|\r|\n)/g, '<br/>');
        let array = replaced.split("<br/>");

        for(let el of array) {
            if(!!el === false) {
                array.splice(array.indexOf(el), 1);
            }
        }

        return "<p>" + array.join("</p><p>") + "</p>";
    }

}
1 Like

It works :slight_smile: Thank you all for quick response and suggestions.

Using CSS’s whitespace: pre-line seems simpler to me.

4 Likes

Didn’t know that existed, that’s quite handy! Though I think it would vary on a case to case basis (or just preference), at least for me. In some cases I’d want the paragraphs instead :wink: News posts? Paragraphs. Chat messages? whitespace: pre-line.

I used this code to replace \n with new line but it is not effective

.ion-card-content {
    white-space: pre-line !important;
  }

1 Like