1

I'm not exactly sure what to call this so I might have missed some things in my search for an answer for this but basically I have data that comes in from an external api and it gets inserted into an innerHTML tag now in the data that is being returned is some html which then gets processed thanks to innerHTML but I have certain keywords in the returned html like this [username] and I want to replace that with data I have stored. So in my .ts file I might have..

username: 'name';

then in my html I have

<div class='inner-html' [innerHTML]="data.html"></div>

and in my response from data.html the html is like so

<h1>Hey [userName] lorem ipsum...</h1>

so I want to replace the [userName] that comes in dynamically from the external api with the username that is stored in username

I tried to put {{username}} in the html that is coming in.. but that didnt work and I also tried ${username} but that also didnt work..

Im wondering if there is another way?

EDIT Ive tried to use str.replace(); in the onChanges life cycle event but that isn't working either my code is ..

  const html = <HTMLElement>document.querySelector('.inner-html');
  html.innerHTML.replace('[userName]', this.username);

Now something like this must be possible, any help would be appreciated

Thanks

3
  • Possible duplicate of String interpolation inside innerHTML in angular 2 Commented Mar 20, 2018 at 3:33
  • @Narm its a different question and that post doesnt have a clear answer anyway Commented Mar 20, 2018 at 3:42
  • 1
    @A61NN5 - please check my answer, I think you'll be pleased. Commented Mar 23, 2018 at 5:19

3 Answers 3

2
+50

Angular provides the Pipe precisely for this purpose:

Pipe

An Angular pipe is a function that transforms input values to output values for display in a view.

They provide reusable and scalable ways of accomplishing your goal. Please check this out as I think it is what you are after:

Live Solution

Basically, you pipe the output of the [innerHTML] through a transform:

<div class='inner-html' [innerHTML]="data.html | parseInnerHtml:replacements"></div>

parseInnerHtml is the custom pipe and it takes a hash of replacement keys and corresponding values to replace with:

import { Input, Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'parseInnerHtml'})
export class ParseInnerHtml implements PipeTransform {
  transform(text: string, replacements: Object): string {
    let search = Object.keys(replacements);
    for(let i = 0; i < search.length; i++){
      text = text.replace('['+ search[i] +']', replacements[search[i]]);
    }
    return text;
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

You should modify you replacement method so that it works if the string to replace is there more than one time
Good suggestion, but I'll allow the OP to do that if so desired. I've answered the question as asked.
@Randy Casburn Hey there just one quick question.. this works perfectly but.. Im getting an error in the console that says cannot convert undefined or null to object on line 5 of the parseInnerHtml pipe Im assuming this is because the data hasnt come in yet before this call is made.. is there anyway to avoid this??
That sounds like you didn't create an object that has the replacements. this is shown in the solution in app.component.ts @ line 9. Did you create?
0

It looks like you have control of the dynamic data. If that is so, It would make more sense if you could transform the html on the server to include the username.

However if you don't have control, you could easily use replace the [username] with what you have. E.G:

str.replace('[username]', this.username);

1 Comment

The question was how to accomplish this with Angular 5.
0
-- in hello.component.ts
@Component({
  selector: 'hello',
  template: ``,
})
export class HelloComponent  {
  @Input() username: string;

  private _html: string;
  @HostBinding('innerHTML')
  @Input() set html(html: string) {
    this._html = html.replace('[userName]', this.username);
  }

  get html() {
     return this._html;
  }
}

-- in app.component.html
<hello [html]="html" [username]="username"></hello>

-- in app.component.ts
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  username = 'App user';
  html = '<h1>Hello [userName]!</h1>';
}

Live example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.