28

Using Angular 5 and Firebase, I am storing and retrieving movie review information. When creating and editing the review, line breaks are kept (I assume using an ngModel has something to do with this). However, when retrieving the review from a reader's perspective, the ReviewComponent, the line breaks are not kept. Logging the body still shows the line breaks and using Angular's json pipe shows as text\n\ntext showing where the line breaks should be.

Here is my HTML:

<main role="main" class="container">
  <p style="margin-bottom: 2rem;">{{review.body}}</p>
</main>

I have also tried span and body.

How can I keep these line breaks in the review for the reader?

cfoster5
  • 1,696
  • 5
  • 28
  • 42
  • What are you using for creating and editing the reviews, a standard `textarea` element or a third-party rich text editor? – Jon P Mar 13 '18 at 00:43
  • 1
    Possible duplicate of [angularjs newline filter with no other html](https://stackoverflow.com/questions/13964735/angularjs-newline-filter-with-no-other-html) – Jon P Mar 13 '18 at 00:51

4 Answers4

53

HTML, in general, uses br tags to denote a new line. A plain textarea tag does not use this, it uses whatever the user's system uses to denote a new line. This can vary by operating system.

Your simplest solution is to use CSS

<main role="main" class="container">
  <p style="margin-bottom: 2rem;white-space:pre-wrap;">{{review.body}}</p>
</main>

This will maintain any "white space" formatting, including additional spaces.

If you want to actually replace the newline characters with br tags you can use the following regex

<main role="main" class="container">
  <p style="margin-bottom: 2rem;" [innerHTML]="review.body.replace(/(?:\r\n|\r|\n)/g, '<br>')"></p>
</main>

Edit Thanks to ConnorsFan for the heads up on replace not working with interpolation.

Jon P
  • 19,442
  • 8
  • 49
  • 72
  • 1
    Did you try the second solution? I think it works with `[innerHTML]` but not with interpolation. See [this stackblitz](https://stackblitz.com/edit/template-driven-form-2-sqx1fq). – ConnorsFan Mar 13 '18 at 01:05
  • I forgot to mention: it doesn't seem to work with regular expressions either, but it works when replacing a string. The syntax available in the template is somewhat limited. – ConnorsFan Mar 13 '18 at 01:23
  • What is `margin-bottom: 2rem` for? Consider removing from the code if irrelevant – Anton Duzenko Jan 29 '21 at 14:36
  • @AntonDuzenko, it is part of the code in the original question. There is no reason to remove it as it would serve a purpose for the original author. – Jon P Jan 31 '21 at 21:54
25

by using the [innerText] directive the white spaces seem to be maintained, as well as the \n new lines

e.g. <small style="display:block" [innerText]="review.body"></small>

JustLearning
  • 3,164
  • 3
  • 35
  • 52
  • 3
    I'm pulling the text from a DB, so `[innerHtml]` seemed susceptible to JS injection. Using `[innerText]` works great for just maintaining white space for me. – MacK Apr 07 '21 at 12:56
  • I see that using `[innerText]` results in Angular (or the browser) converting the new-line characters into `
    ` tags.
    – Zarepheth Mar 02 '22 at 20:15
  • For Angular, this is the solution – manish joshi Jun 24 '22 at 18:05
6

I had a similar situation where I had HTML code like this:

<div>{{msgTitle}}</div>

And I tried putting both '\r\n' and &lt;br&gt; in the string msgTitle, but neither of them worked to put a newline in the text displayed on the page. This link gave me the solution:

https://github.com/angular/angular/issues/7781

Use [innerHTML]="msgTitle" instead of {{msgTitle}}.

JustLearning
  • 3,164
  • 3
  • 35
  • 52
John Gilmer
  • 831
  • 1
  • 11
  • 18
-5

try span but set it like that:

span 
{ 
    display : table;
}

it should helps.

Jon P
  • 19,442
  • 8
  • 49
  • 72
Piotr Mirosz
  • 846
  • 9
  • 20