1

I'm using a highlight pipe in Angular's appComponent to highlight search text displayed in the router-outlet from another component but I don't know how to use the pipe in a component (not in a template).

What I currently have in app.component.ts:

import { Component, OnInit } from '@angular/core';
import { HighlightPipe } from './shared/highlight-pipe';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [ HighlightPipe ]
})

export class AppComponent {
  constructor(private highlight: HighlightPipe) {}

  startSearch(searchTerm: string) {
    if (!searchTerm) {
      return;
    }
    const content = document.getElementById('content');
    if (content) {
      const mainContent = content.children;

      for (let i = 0; i < content.length; i++) {
        **content[i].innerHTML = 'content[i].innerHTML | this.highlight: searchTerm';** <-- here
      }
    }
  }
}

My app.component.html:

<app-header (searchEvent)="startSearch($event)"></app-header>
<router-outlet></router-outlet>

My highlight-pipe.ts:

import {PipeTransform, Pipe} from '@angular/core';

@Pipe({ name: 'highlight' })
export class HighlightPipe implements PipeTransform {
  transform(text: string, search): string {
    let pattern = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
    pattern = pattern.split(' ').filter((t) => {
      return t.length > 0;
    }).join('|');
    const regex = new RegExp(pattern, 'gi');

    return search ? text.replace(regex, (match) => `<span class="highlight">${match}</span>`) : text;
  }
}

So (predictably) my output currently just repeatedly prints the string content[i].innerHTML | this.highlight: searchTerm in the <router-outlet>

I've seen other articles that talk about using *ngFor but *ngFor is used in a template. But in my case, when someone tries to do a search in the header (not App) component, the header component simply emits the searchEvent event that is then received in the AppComponent template, which triggers startSearch in AppComponent... so I have to use the pipe in AppComponent instead of in the header.

Is it possible to use a pipe in a plain JS for loop in a component instead of in a template in Angular?

1 Answer 1

2

EDIT:

With the pipe added to your constructor:

constructor(private highlight: HighlightPipe) {} 

Then you can use:

content[i].innerHTML = this.highlight(content[i].innerHTML, "searchTerm")
Sign up to request clarification or add additional context in comments.

2 Comments

this works great. just needed to call the transform method on the pipe: content[i].innerHTML = this.pipe.transform(content[i].innerHTML, "searchTerm")
also had to add the pipe to providers in @Component like so: @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], providers: [ HighlightPipe ] }) Sorry, formatting not so pretty in the comments section...

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.