Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular4 routerLink inside innerHTML turned to lowercase

I have a cmd where I get the content of the page from the server. Then content can include HTML and links. The problem is when I display this data the links don't work. When looking at page source it turns out that "routerLink" is transformed into "router link" and that's why it probably doesn't work. Here is my code:

My class, notice that routerLink is in camelcase here:

export class TwoComponent implements OnInit {
  data = '<a routerLink="/one">ONE</a>'; //this will actually come from backend server

  constructor() { }

  ngOnInit() {}
}

And my html:

<div [innerHTML]="data | bypassSecurity"></div>

And when i load this page and look at the source the routerLink is now in lowercase:

<a routerlink="/one">ONE</a>

At first, i thought it's the bypassSecurity pipe that responsible but I checked the output of the pipe and routerLink was still in camel case there. So it seems like it happens somewhere else. Just in case here is my bypassSecurity pipe too:

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

  transform(value): any {
    return this.sanitized.bypassSecurityTrustHtml(value);
  }
}

Any advice on where and why this lowercase transformation happens would be appreciated :)

like image 739
user1985273 Avatar asked Jun 18 '17 08:06

user1985273


2 Answers

jcdsr's solution helped me a lot. I got this working by using it with DomSanitizer.

Here is how i did:

RouteTransformerDirective

import { Directive, ElementRef, HostListener } from '@angular/core';
import { Router } from '@angular/router';

@Directive({
  selector: '[routeTransformer]'
})
export class RouteTransformerDirective {

  constructor(private el: ElementRef, private router: Router) { }

  @HostListener('click', ['$event'])
  public onClick(event) {
    if (event.target.tagName === 'A') {
      this.router.navigate([event.target.getAttribute('href')]);
      event.preventDefault();
    } else {
      return;
    }
  }

};

Component

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

public html: SafeHtml;

constructor(private sanitizer: DomSanitizer) {
    this.html = sanitizer.bypassSecurityTrustHtml('<a href="/something">Link</a>');
}

Template

<div [innerHtml]="html" routeTransformer></div>
like image 148
Efe Avatar answered Nov 07 '22 11:11

Efe


This is my solution, you only need to use html5 attributes.

on template:

        <div [innerHtml]="testHtml" (click)="getRoute($event)"></div>

in component:

        import { Component, OnInit } from '@angular/core';
        import { Router } from '@angular/router';

        @Component({
          selector: 'app',
          templateUrl: './app.component.html',
          styleUrls:['./app.component.css'],

        })

        export class oneComponent implements OnInit {

            testHtml: any;

            constructor( private router: Router,) {}

            this.testHtml=`
            <br>
            ------- <span data-link="/page 1">Page 1</span> ------- 
            <br>
            ------- <a data-link="/page 2">Page 2</a> ------- 
            <br>
            text -- `;


            getRoute(event) {
                var goRoute = event.target.getAttribute('data-link')
                alert(goRoute);
                this.router.navigate([goRoute]);
            }
        }

or as directive,

        import { Directive, ElementRef, HostListener } from '@angular/core';
        import { Router } from '@angular/router';

        @Directive({     
            selector: '[routeDirective]'
        })

        export class routeDirective {

          constructor(private el: ElementRef, private router: Router) { }

            @HostListener('click', ['$event.target']) onClick($event){
                console.info('clicked: ' + $event.getAttribute('data-link'));
                var goRoute = $event.getAttribute('data-link');
                this.router.navigate([goRoute]);

            }


        }

on template as directive:

        <div [innerHtml]="testHtml" routeDirective></div>

disadvantages:

Search engines are fine with "a tag" with no attributes. They won't see it as a link and they won't try to pass link juice to it - SEO.

like image 14
jcdsr Avatar answered Nov 07 '22 10:11

jcdsr