1

Used two pipes to make an html markup, from my database, safer and shorter:

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(protected sanitizer: DomSanitizer) {}

     public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
        switch (type) {
                case 'html': return this.sanitizer.bypassSecurityTrustHtml(value);
                . . .
            }
      }
    }

and

@Pipe({
  name: 'summary'
})
export class SummaryPipe implements PipeTransform {

  transform(content: string, characterLimit: number): string {
    if (content.length <= characterLimit) {
      return content;
    } else {
      return `${content.substring(0, characterLimit)}...`;
    }
  }

}

Using it with one pipe it works:

<div [innerHtml]="blog.content | safe: 'html'"></div>

But with the second pipe it stops showing:

<div [innerHtml]="blog.content | safe: 'html' | summary:100"></div>

How can I fix it ?

Sami-L
  • 5,553
  • 18
  • 59
  • 87

2 Answers2

3

Your summary pipe is expecting a string, but your safe pipe return a SafeValue.

You should use the safe pipe last:

<div [innerHtml]="blog.content | summary:100 | safe: 'html'"></div>

This is the only way to get it working in this specific case because the summary pipe return a new unsafe string. It would get sanitized by innerHtml automatically if used last.

Since the bypassSecurityTrustHtml don't change the value at all, it's safe to call it last. If you do need to sanitize the string (remove html elements), just pass a string directly to innerHtml without any bypass method and it will be sanitized for you.

  • You're right, this is a type issue. using "summary" pipe before "safe" pipe works, but none of the other solutions worked for me. and I keep wondering as the summary pipe should shorten the content to a certain number of characters starting from 0, how the html markup still works while the closing tags at the end are suppressed ? – Sami-L Apr 20 '22 at 13:21
  • All the `bypassSecurityTrustX` methods don't modify the string at all, it only mark it as safe. Now that I think about it, using the summary pipe after safe would never work since it return a new unsafe string. If you truly need to suppress the html tags, simply passing an unsafe string to `innerHtml` should sanitize it. – Yannick Beauchamp-H Apr 20 '22 at 16:02
  • I edited my answer. Also, the browser is pretty lenient when parsing html with missing closing tags. That's why it still work with the closing tag missing. Depending on where the string is truncated, it might not parse correctly. It doesn't seems like a good idea to use innerHtml with partial html. – Yannick Beauchamp-H Apr 20 '22 at 16:59
0
  <div [innerHtml]="(blog.content | safe: 'html') | summary:100"></div>

did you try doing this?