How to truncate text in Angular2?

AngularAngular2 Template

Angular Problem Overview


Is there a way that I could limit the length of the string to a number characters? for e.g: I have to limit a title length to 20 {{ data.title }}.

Is there any pipe or filter to limit the length?

Angular Solutions


Solution 1 - Angular

> Two way to truncate text into angular.

let str = 'How to truncate text in angular';

1. Solution

  {{str | slice:0:6}}

Output:

   how to

If you want to append any text after slice string like

   {{ (str.length>6)? (str | slice:0:6)+'..':(str) }}

Output:

 how to...

2. Solution(Create custom pipe) > if you want to create custom truncate pipe

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

@Pipe({
 name: 'truncate'
})

export class TruncatePipe implements PipeTransform {

transform(value: string, args: any[]): string {
    const limit = args.length > 0 ? parseInt(args[0], 10) : 20;
    const trail = args.length > 1 ? args[1] : '...';
    return value.length > limit ? value.substring(0, limit) + trail : value;
   }
}

In Markup

{{ str | truncate:[20] }} // or 
{{ str | truncate:[20, '...'] }} // or

Don't forget to add a module entry.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}

Solution 2 - Angular

Truncate Pipe with optional params:

  • limit - string max length

  • completeWords - Flag to truncate at the nearest complete word, instead of character

  • ellipsis - appended trailing suffix

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 25, completeWords = false, ellipsis = '...') {
    if (completeWords) {
      limit = value.substr(0, limit).lastIndexOf(' ');
    }
    return value.length > limit ? value.substr(0, limit) + ellipsis : value;
  }
}

Don't forget to add a module entry.

@NgModule({
  declarations: [
    TruncatePipe
  ]
})
export class AppModule {}

Usage

Example String:

public longStr = 'A really long string that needs to be truncated';

Markup:

  <h1>{{longStr | truncate }}</h1> 
  <!-- Outputs: A really long string that... -->

  <h1>{{longStr | truncate : 12 }}</h1> 
  <!-- Outputs: A really lon... -->

  <h1>{{longStr | truncate : 12 : true }}</h1> 
  <!-- Outputs: A really... -->

  <h1>{{longStr | truncate : 12 : false : '***' }}</h1> 
  <!-- Outputs: A really lon*** -->

Solution 3 - Angular

You can truncate text based on CSS. It helps to truncate a text based on width not fix character.

Example

CSS

.truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.content {
    width:100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

HTML

<div class="content">
    <span class="truncate">Lorem Ipsum is simply dummied text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</span>
</div>

Note: this code use full for one line not for more than one.

Ketan's Solution is best if you want to do it by Angular

Solution 4 - Angular

Like this:

{{ data.title | slice:0:20 }}

And if you want the ellipsis, here's a workaround

{{ data.title | slice:0:20 }}...

Solution 5 - Angular

Limit length based on words

Try this one, if you want to truncate based on Words instead of characters while also allowing an option to see the complete text.

Came here searching for a Read More solution based on words, sharing the custom Pipe i ended up writing.

Pipe:

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

@Pipe({
  name: 'readMore'
})
export class ReadMorePipe implements PipeTransform {

  transform(text: any, length: number = 20, showAll: boolean = false, suffix: string = '...'): any {
    
    if (showAll) {
      return text;
    }

    if ( text.split(" ").length > length ) {
      
      return text.split(" ").splice(0, length).join(" ") + suffix;
    }

    return text;
  }

}

In Template:

<p [innerHTML]="description | readMore:30:showAll"></p>
<button (click)="triggerReadMore()" *ngIf="!showAll">Read More<button>

Component:

export class ExamplePage implements OnInit {

	public showAll: any = false;
	
	triggerReadMore() {
		this.showAll = true;
	}
	
}

In Module:

import { ReadMorePipe } from '../_helpers/read-more.pipe';

@NgModule({
  declarations: [ReadMorePipe]
})
export class ExamplePageModule {}

Solution 6 - Angular

Here's an alternative approach using an interface to describe the shape of an options object to be passed via the pipe in the markup.

@Pipe({
  name: 'textContentTruncate'
})
export class TextContentTruncatePipe implements PipeTransform {

  transform(textContent: string, options: TextTruncateOptions): string {
    if (textContent.length >= options.sliceEnd) {
      let truncatedText = textContent.slice(options.sliceStart, options.sliceEnd);
      if (options.prepend) { truncatedText = `${options.prepend}${truncatedText}`; }
      if (options.append) { truncatedText = `${truncatedText}${options.append}`; }
      return truncatedText;
    }
    return textContent;
  }

}

interface TextTruncateOptions {
  sliceStart: number;
  sliceEnd: number;
  prepend?: string;
  append?: string;
}

Then in your markup:

{{someText | textContentTruncate:{sliceStart: 0, sliceEnd: 50, append: '...'} }}

Solution 7 - Angular

Very simple using slice pipe (angular's core pipe), as you asked for data.title:

{{ data.title | slice:0:20 }}

From Angular common docs https://angular.io/api/common/SlicePipe

Solution 8 - Angular

I've been using this module ng2 truncate, its pretty easy, import module and u are ready to go... in {{ data.title | truncate : 20 }}

Solution 9 - Angular

If you want to truncate by a number of words and add an ellipsis you can use this function:

truncate(value: string, limit: number = 40, trail: String = '…'): string {
  let result = value || '';

  if (value) {
    const words = value.split(/\s+/);
    if (words.length > Math.abs(limit)) {
      if (limit < 0) {
        limit *= -1;
        result = trail + words.slice(words.length - limit, words.length).join(' ');
      } else {
        result = words.slice(0, limit).join(' ') + trail;
      }
    }
  }

  return result;
}

Example:

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 5, '…')
> "Bacon ipsum dolor amet sirloin…"

taken from: https://github.com/yellowspot/ng2-truncate/blob/master/src/truncate-words.pipe.ts

If you want to truncate by a number of letters but don't cut words out use this:

truncate(value: string, limit = 25, completeWords = true, ellipsis = '…') {
  let lastindex = limit;
  if (completeWords) {
    lastindex = value.substr(0, limit).lastIndexOf(' ');
  }
  return `${value.substr(0, limit)}${ellipsis}`;
}

Example:

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 19, true, '…')
> "Bacon ipsum dolor…"

truncate('Bacon ipsum dolor amet sirloin tri-tip swine', 19, false, '…')
> "Bacon ipsum dolor a…"

Solution 10 - Angular

Just tried @Timothy Perez answer and added a line

if (value.length < limit)
   return `${value.substr(0, limit)}`;

to

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

@Pipe({
  name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit = 25, completeWords = false, ellipsis = '...') {

   if (value.length < limit)
   return `${value.substr(0, limit)}`;

   if (completeWords) {
     limit = value.substr(0, limit).lastIndexOf(' ');
   }
   return `${value.substr(0, limit)}${ellipsis}`;
}
}

Solution 11 - Angular

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

@Pipe({
  name: 'truncate',
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit: number, trail = '...'): string {
    if (value.length <= limit) {
      return value;
    }

    return value.substring(0, limit - trail.length).replace(/\s+$/, '') + trail;
  }
}
{{ str | truncate: 20 }}
{{ str | truncate: 20:'>>>'] }}

If you need truncate by words:

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

@Pipe({
  name: 'truncateByWords',
})
export class TruncateByWordsPipe implements PipeTransform {
  transform(value: string, limit: number, trail = '...'): string {
    if (value.length <= limit) {
      return value;
    }

    const substr = value.substring(0, limit - trail.length).split(' ');
    const isLastWordFull = value
      .split(' ')
      .find(w => w === substr[substr.length - 1]);

    if (isLastWordFull) {
      return substr.join(' ') + trail;
    }

    return substr.slice(0, -1).join(' ') + trail;
  }
}
{{ str | truncateByWords: 20 }}
{{ str | truncateByWords: 20:'>>>'] }}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhimView Question on Stackoverflow
Solution 1 - AngularKetan AkbariView Answer on Stackoverflow
Solution 2 - AngularTimothy PerezView Answer on Stackoverflow
Solution 3 - AngularShailesh LadumorView Answer on Stackoverflow
Solution 4 - AngularMcCoyView Answer on Stackoverflow
Solution 5 - AngularShahbaz A.View Answer on Stackoverflow
Solution 6 - AngularcssimsekView Answer on Stackoverflow
Solution 7 - AngularIgnacio AraView Answer on Stackoverflow
Solution 8 - AngularKerim092View Answer on Stackoverflow
Solution 9 - AngularGianfranco P.View Answer on Stackoverflow
Solution 10 - Angularunos baghaiiView Answer on Stackoverflow
Solution 11 - AngularEugene P.View Answer on Stackoverflow