How to extract the first initials from a full name using Angular TypeScript and *ngFor

I am new to Angular and still learning about its functionalities. Currently, I am developing an Angular app where I need to display a list of people. In case there is no picture available for a person, I want to show the first letters of their first name and last name as 'DP'. The code snippet I am working on looks like this:

<div class="people" *ngFor="let user of users">
    <div class="s-profile-icon">
        <img src={{user.picture}} alt="Profile" />
    </div>
    <div class="s-name">
        {{user.full_name}}
    </div>
</div>

I know that I can use *ngIf directive on user.picture to check if the picture is empty. However, my challenge lies in getting the first letters of the user's name. For instance, if the user.full_name is 'Mary Johnson' and there is no picture available, then instead of displaying an image, it should show 'MJ'. I have the circle design ready to display these letters, but I'm unsure how to extract the first letters within the loop. If anyone has insights on how to achieve this, I would greatly appreciate your help.

Answer №1

To achieve a shortened name display, you have two options. You can either create a custom method in your component or develop a custom Angular pipe.

Method for obtaining a short name:

getShortName(fullName) { 
  return fullName.split(' ').map(n => n[0]).join('');
}

Template usage:

<div class="people" *ngFor="let user of users">
    <div class="s-profile-icon">
        <img src={{user.picture}} alt="{{getShortName(user.full_name)}}" />
    </div>
    <div class="s-name">
        {{getShortName(user.full_name)}}
    </div>
</div>

Update 🔥

The approach above is considered bad practice as the method runs in every change detection cycle. The recommended approach is to use a custom pipe to retrieve the short name.

shortName.pipe.ts

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

@Pipe({
  name: "shortName"
})
export class ShortNamePipe implements PipeTransform {
  transform(fullName: string): any {
    return fullName
      .split(" ")
      .map(n => n[0])
      .join("");
  }
}

Usage in template:

{{'My Name' | shortName}}

Check out the demo 🚀

Answer №2

To handle this situation effectively, consider creating a custom pipe: https://angular.io/guide/pipes

Pipes serve as converters that transform model values into display values. Once you have implemented your pipe, simply use it in your template like so:

<div class="s-name">
    {{user.full_name | myCustomNamePipe }}
</div>

Alternatively, you can bind to a method within the component. However, this approach may be less efficient due to how change detection works:

<div class="s-name">
    {{ getNamePieces(user) }}
</div>

Another option is to create a user view model and pre-select data for display using map, allowing you to directly bind to a calculated property.

Answer №3

I have enhanced the solution originally created by @malbarmavi, which can be found at

An additional parameter has been added to the pipe to allow users to specify the number of characters to display.

shortName.pipe.ts

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

@Pipe({
  name: "shortName"
})
export class ShortNamePipe implements PipeTransform {
  transform(fullName: string, numChars: number = 2): any {
    return fullName
    .split(" ").slice(0,numChars)
      .map(n => n[0].toUpperCase())
      .join("");
  }
}

template

{{'My Name' | shortName:2}}

demo 🚀

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Best practice for encapsulating property expressions in Angular templates

Repeating expression In my Angular 6 component template, I have the a && (b || c) expression repeated 3 times. I am looking for a way to abstract it instead of duplicating the code. parent.component.html <component [prop1]="1" [prop2]="a ...

What is the best way to host a single page application within a sub-directory using nginx?

Trying to set up nginx to host an Angular application from a unique child path. Adjusted the app to use a base href of fish, able to serve root page and assets correctly. However, encountering a 404 error when attempting to reload the page on a child rout ...

Rotating images on a canvas

We're currently implementing Ionic and Angular in our project. One issue we are facing is regarding image rotation on canvas. When we click on an image, the rotation works perfectly if it's a jpg file. However, when we pass a base64 image, the r ...

Mastering the Art of Injecting Objects from the Server

Utilizing Angular Universal, I am serving my Angular application through an Express server. The objective is to embed an environment object (from the server) into my application. To achieve this, I have created an InjectionToken export const ENVIRONMENT ...

Angular 4 allows for dynamically applying the active class to a clicked button, enhancing interactivity

Issue: <button *ngFor="let button of buttons" [ngClass]="{'active': isClicked}" (click)="isClicked = !isClicked" Description: A total of 10 buttons are displayed on the screen. When I click on button number 1, each button receives the clas ...

Guide to sending a HTTP POST request with parameters in typescript

I need assistance sending a POST request using parameters in the following format: http://127.0.0.1:9000/api?command={"command":"value","params":{"key":"value","key":"value","key":"value","key":value,}} I attempted to do this but encountered an issue: l ...

Show Timing on the Y-Axis - Bubble Graph

Recently, I stumbled upon the Bubble Chart feature in ng2-charts. I am trying to display data based on time on the Y-axis and values on the X-axis. My dataset consists of x:[10,35,60], y:["7.00 AM"], with r having the same value as x. However, the sample d ...

What is the best way to initialize elements once the data has finished loading?

I am currently working with a service class that retrieves data through HTTP in several methods. For example: filesPerWeek(login: string): Observable<FilesLastActivity[]> { return this.http.get('api/report/user_files_by_week?userId=' + ...

Prevent selecting dates beyond the current date in Formly Datepicker within Angular

How can I disable future dates in Formly with Material datepicker in Angular? Despite searching online, I am unable to find a solution! export class AppComponent { form = new FormGroup({}); model: any = {}; options: FormlyFormOptions = {}; fields: ...

What is the best way to incorporate the "child_process" node module into an Angular application?

Trying to execute a shell script in my Angular application has been quite the challenge. I came across the "child process" node library that might be able to help me with this task. However, every attempt to import the library led me to the error message: ...

In TypeScript, the catch block does not get triggered

I created a custom pipe in Angular that is supposed to format passed parameters to date format. The pipe contains a try-catch block to handle any errors, but surprisingly the catch block never seems to be executed even when an invalid date is passed. impo ...

Is there an alternative to RequestOptionsArgs that I can use in this function?

I am currently working on updating an existing Angular application from version 4.3 to Angular 8. One of the challenges I'm facing is replacing old component classes like ConnectionBackend, RequestOptions, and RequestOptionsArgs with their updated equ ...

There was an issue encountered when creating the class: The parameters provided do not correspond to any valid call target signature

I am facing an issue with my code. Here is the scenario: export class MyClass { public name:string; public addr:string; constructor() {} } I have imported MyClass and trying to use it like this: import { MyClass } from './MyClass' ...

Receiving an error in Typescript when passing an object dynamically to a React component

Encountering a typescript error while attempting to pass dynamic values to a React component: Error message: Property 'title' does not exist on type 'string'.ts(2339) import { useTranslation } from "react-i18next"; import ...

Tips for transferring information between service functions in Angular

In my front-end development, I am working on creating a store() function that adds a new question to the database. However, I need to include the active user's ID in the question data before sending it to the back-end. Below is the code for the store ...

Getting an Angular TypeError after upgrading to version 9? It seems that the property 'selectors' cannot be read from null

After upgrading my Angular app from v7 to v8 and then v8 to v9, I encountered an issue. My app works perfectly locally when I run ng serve, but when I build for production using ng build --prod and deploy the app, I get an error in the application's c ...

Deleting an element from an object in TypeScript

Is there a way in TypeScript to exclude certain elements (e.g. 'id') from an object that contains them? ...

Determining the quantity of variations within a union in Typescript

Is it possible to determine the number of types in a union type in Typescript, prior to runtime? Consider the following scenario: type unionOfThree = 'a' | 'b' | 'c'; const numberOfTypes = NumberOfTypes<unionOfThree>; c ...

Pass an array of objects to an Angular 8 component for rendering

Recently, I started working with Angular 8 and faced an issue while trying to pass an array of objects to my component for displaying it in the UI. parent-component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: ...

Validating dynamic forms with multiple rows in Angular 9

I am looking for a way to consolidate validation errors in one place for multiple rows created dynamically based on user input. Instead of displaying the error message next to each field, I want all the validation errors for each row to be displayed collec ...