1

I'm trying to write a pipe that can make any words with #hashtaginto a url exactly like twitter.

This is the function in my pipes that generates converts #tags into urls.

urlifyHashtags(_text) : String {
let hashtagRegex = /^#([a-zA-Z0-9]+)/g;
let tempText = _text.replace(hashtagRegex, " <a [routerLink]=\"['/search/hash/aaa']\" routerLinkActive=\"active-link\">#$1</a>");
var hashtagRegex2 = /([^&])#([a-zA-Z0-9]+)/g;
tempText = tempText.replace(hashtagRegex2, "<a [routerLink]=\"['/search/hash/' , 'Russ']\" routerLinkActive=\"active-link\"> #$2</a>");
return tempText;
}

And this is where it goes to:

    <p *ngIf="!editable" [innerHTML] ="item.body | bodyHashtag"></p>

Any help/advice much appreciated.

Hadi
  • 11
  • 1

2 Answers2

1

You must sanitize your HTML while injecting HTML using [innerHTML], by using DomSanitizer provider with SafeHtml.

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'


export class myCustomPipe implements PipeTransform 
{
    constructor(private sanitized: DomSanitizer) {}

    transform(value: string): SafeHtml{
       return this.sanitized
                  .bypassSecurityTrustHtml(this.urlifyHashtags(value));
    }

    urlifyHashtags(_text) : String {
            let hashtagRegex = /^#([a-zA-Z0-9]+)/g;
            let tempText = _text.replace(hashtagRegex,"<a [routerLink]=\"['/search/hash/aaa']\" routerLinkActive=\"active-link\">#$1</a>");
            var hashtagRegex2 = /([^&])#([a-zA-Z0-9]+)/g;
            tempText = tempText.replace(hashtagRegex2, "<a [routerLink]=\"['/search/hash/' , 'Russ']\" routerLinkActive=\"active-link\"> #$2</a>");
            return tempText;
     }

}
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • Thanks, but Gunter is right. Your solution helps with bypassing angular security model however the routerLink don't work – Hadi Aug 29 '17 at 16:10
1

Angular doesn't process HTML added dynamically. Event though you might be able to add the HTML using the method micronyks explained, Angular won't make an router link from this HTML. Angular only processes HTML (except sanitization for security purposes) for HTML added statically to a components template.

What you can do though is to create bound values dynamically

<a [routerLink]="someStringFromComponentClass" routerLinkActive="active-link">{{boundValue}}</a>

If you actually need to build this dynamically, you can create and add a component at runtime like explained in How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Correct! Now I don't get the security error but it also dooesn't work as url. – Hadi Aug 29 '17 at 16:08
  • I'm not sure if I understand your solution though : ( Sorry I'm new to angular – Hadi Aug 29 '17 at 16:09
  • 1
    Agreed!!. I didn't think about it. @Hadi if you are adding an angular context in HTML, it will not work and `[routerLink]` is part of angular functionality. – micronyks Aug 29 '17 at 16:13
  • @Hadi I'm not sure what exactly you try to accomplish. My answer covers only a part of your problem. You could just move the regex stuff to the components class and assign the result to a property and then using bindings to bind the values to `routerLink`. `someStringFromComponentClass` and `boundValue` are such fields where you assign the calculated values. – Günter Zöchbauer Aug 29 '17 at 16:18
  • Thanks so much, I will look into this and get back to you. – Hadi Aug 29 '17 at 16:19