Search code examples
htmlangularcomponentsangular-components

In Angular how do I dynamically wrap certain words in another html element?


I have this simple Angular Component:

@Component({
  selector: 'my-component',
  template: '<p>{{someString}}</p>',
})
export class MyComponent  {
  @Input() someString: string;
}

someString could be any string of any length. As an example, imagine that someString's value is :

"If you want my body and you think I'm sexy, come on, sugar, tell me so."

In that case the HTML generated by Angular would essentially be equivalent to:

<p>If you want my body and you think I'm sexy, come on, sugar, tell me so.</p>

How would I modify MyComponent so that it detects each occurrence of the word sexy in someString and have Angular wrap that word in another HTML element such as <b>. So in this example case it would generate something like:

<p>If you want my body and you think I'm <b>sexy</b>, come on, sugar, tell me so.</p>

What if I wanted to wrap every occurrence of the word sexy in an Angular Component instead of a native HTML Element? Would that necessitate a different approach?


Solution

  • This solution avoids using innerHTML and relies strictly on Angular constructs.

    @Component({
      selector: 'my-component',
      template: `
      <p>
        <ng-container *ngFor="let segment of segments">
          <span *ngIf="!segment.shouldBeBold()">segment.text</span>
          <b *ngIf="segment.shouldBeBold()">segment.text</b>
        </ng-container>
      </p>
      `,
    })
    export class MyComponent  {
      @Input() someString: string;
    
      private wordsToBold = new Set(['sexy', 'body', 'sugar']); 
    
      get segments() {
        const regex = this.makeRegex();
        const segments = this.someString.split(regex);
        return segments.map(segment => {
          return { text: segment, shouldBeBold: wordsToBold.has(segment.toLowerCase()) };
        });
      }
    
      private makeRegex() {
        const expression = [...this.wordsToBold].join('\\b|\\b');
        return new RegExp(`(\\b${expression}\\b)+`, 'gi');
      }
    }