Unable to properly display date formatting in AG-Grid using the Angular date pipe

Currently, I am utilizing ag-grid in conjunction with Angular 8. Within my table, there is a column where my intention is to exhibit dates in a concise format. In order to achieve this, I opted to utilize the Angular date pipe. However, it appears that the implementation is encountering issues. The code snippet and error message are provided below:

@Component({
  selector: 'app-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.css']
})
export class SampleComponent implements OnInit {

  @ViewChild('agGrid', {static: true}) agGrid: AgGridAngular;

  rowData: Bidon[] = [];
  columnDefs = [
    {headerName: 'PostId', field: 'postId', sortable: true, filter: true, checkboxSelection: true},
    {headerName: 'Id', field: 'id', sortable: true, filter: true},
    {headerName: 'Name', field: 'name', sortable: true, filter: true},
    {headerName: 'Email', field: 'email', sortable: true, filter: true},
    {headerName: 'Body', field: 'body', sortable: true, filter: true},
    {headerName: 'Date Bidon 1', field: 'dateBindon1', sortable: true, filter: true, valueFormatter: this.datePipeFormatter},
    {headerName: 'Date bidon 2', field: 'dateBidon2', sortable: true, filter: true},
    {headerName: 'Price', field: 'price', sortable: true, filter: true, valueFormatter: this.currencyFormatter}
  ];

  constructor(private bidonService: BidonService, private datePipe: DatePipe) {
  }

  ngOnInit() {
    this.rowData = this.bidonService.bidons;
    console.log(this.datePipe.transform(new Date(), 'short'));
  }

  getSelectedRows() {
    const selectedNodes = this.agGrid.api.getSelectedNodes();
    const selectedData = selectedNodes.map(node => node.data);
    const selectedDataStringPresentation = selectedData.map(node => 'Name: ' + node.name + ' Email: ' + node.email).join(', ');

    console.log(`Selected nodes: ${selectedDataStringPresentation}`);
  }

  currencyFormatter(params) {

    console.log(params);
    return params.value + '$';
  }

  datePipeFormatter(params) {

    return this.datePipe.transform(params.value, 'short');
  }

}

enter image description here

Answer №1

When ag-grid calls your valueFormatter function, the this context is lost, so you need to bind it.

Using bind:

columnDefs = [
    {headerName: 'PostId', field: 'postId', sortable: true, filter: true, checkboxSelection: true},
    {headerName: 'Id', field: 'id', sortable: true, filter: true},
    {headerName: 'Name', field: 'name', sortable: true, filter: true},
    {headerName: 'Email', field: 'email', sortable: true, filter: true},
    {headerName: 'Body', field: 'body', sortable: true, filter: true},
    {headerName: 'Date Bidon 1', field: 'dateBindon1', sortable: true, filter: true, valueFormatter: this.datePipeFormatter.bind(this)},
    {headerName: 'Date bidon 2', field: 'dateBidon2', sortable: true, filter: true},
    {headerName: 'Price', field: 'price', sortable: true, filter: true, valueFormatter: this.currencyFormatter.bind(this)}
  ];

Alternatively, using arrow functions:

columnDefs = [
    {headerName: 'PostId', field: 'postId', sortable: true, filter: true, checkboxSelection: true},
    {headerName: 'Id', field: 'id', sortable: true, filter: true},
    {headerName: 'Name', field: 'name', sortable: true, filter: true},
    {headerName: 'Email', field: 'email', sortable: true, filter: true},
    {headerName: 'Body', field: 'body', sortable: true, filter: true},
    {headerName: 'Date Bidon 1', field: 'dateBindon1', sortable: true, filter: true, valueFormatter: p => this.currencyFormatter(p)},
    {headerName: 'Date bidon 2', field: 'dateBidon2', sortable: true, filter: true},
    {headerName: 'Price', field: 'price', sortable: true, filter: true, valueFormatter: p => this.currencyFormatter(p)}
  ];

Answer №2

Your code is experiencing a problem with the valueFormatter function you have set for the Date Bidon 1 column in the columnDefs array. The issue arises because you are using this.datePipeFormatter as the value formatter, but the context of 'this' inside the function refers to the function itself, not the component instance, leading to the datePipe service being unavailable.

To resolve this issue, you can utilize an arrow function for the datePipeFormatter function, which will maintain the correct context of the component instance. Here's how you can adjust the code:

{headerName: 'Date Bidon 1', field: 'dateBindon1', sortable: true, filter: true, valueFormatter: (params) => this.datePipeFormatter(params)},

By making this change, the problem with the date pipe not functioning properly should be resolved. Additionally, ensure that you import the DatePipe in your component:

import { Component, OnInit, ViewChild } from '@angular/core';
import { AgGridAngular } from 'ag-grid-angular';
import { Bidon } from '../bidon';
import { BidonService } from '../bidon.service';
import { DatePipe } from '@angular/common';
...

Lastly, confirm that DatePipe is included in the providers array of your module:

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [DatePipe], // <-- add DatePipe here
  bootstrap: [AppComponent]
})
export class AppModule { }

After implementing these changes, the date should display correctly in the short format. If any issues persist, feel free to leave a comment and I will assist in resolving them.

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

Having trouble with UpdateMany in mongoose, but it works perfectly in mongodb when executed directly

I am attempting to update and insert data in mongoose. After sending some requests, I receive the following result: let obj = [ {name: aaa, age: 10}, {name: bbb, age: 11}, {name: ccc, age: 12}, ] My goal is to update all existing documents an ...

Is there a way to incorporate my getter into a computed property?

My Vuex Store is built using Vuex module decorators and I am facing an issue with using a getter for a computed property. Here is my code: @Module export default class WorkoutModule extends VuexModule { _workout: Workout; @Mutation startWork ...

Removing the enclosing HTML tag in Angular reactive Forms

I am utilizing a reactive custom control in my code: <div customFormControl formControlName="old"></div> In the component, the selector is defined as: selector: '[customFormControl]', Is there a way to remove the surrounding mar ...

Determine the return type of a function based on a key parameter in an interface

Here is an example of a specific interface: interface Elements { divContainer: HTMLDivElement; inputUpload: HTMLInputElement; } My goal is to create a function that can retrieve elements based on their names: getElement(name: keyof Elements): Elemen ...

Declaring TypeScript functions with variable numbers of parameters

Is it possible to define a custom type called OnClick that can accept multiple types as arguments? How can I implement this feature so that I can use parameters of different data types? type OnClick<..> = (..) => void; // example usage: const o ...

Discovering different types of navigation in React Navigation using navigationRef

I'm currently working on adding types to my TypeScript version of this function, but I'm facing some difficulties with it. Perusing the React Navigation documentation: // RootNavigation.js import { createNavigationContainerRef } from '@rea ...

Strategies for managing various errors that can arise when multiple Angular components are subscribed to a single state

My Angular application is facing a dilemma with three components at play: Component #1: Shows a list of items Component #2: Displays recently used items Component #3: Exhibits the current item For now, let's assume they're all visible on the sa ...

Tips for extracting a value from a geojson response using a specific key

When analyzing the geojson response below, I am trying to access the following: Type and Segments To achieve this, I attempted the following: return data["type"] //does not work, error received return data["features"][0]["properties"]["segments"] ...

Generate a commitment from the function

I know the basics of JavaScript Promise and promise chain, but I'm looking to deepen my understanding. For example, take a look at the method provided below. It's in TypeScript, but can be adjusted for JavaScript ES6. private InsertPersonInDB(p ...

Retrieving the value of an object using an array of keys

Consider the following object: const obj = { A:{ a1:'vala1', a2:'vala2' }, B:{ b1: 'valb1', b2: 'valb2' }, C:{ c1:{ c11:'valc11' }, c2:'valc2' } } We also have an array: const ...

What is the title of the commonly used state management approach in rxjs? Are there any constraints associated with it?

When working with Angular applications, it is common to use the following approach to manage shared states: import { BehaviorSubject } from 'rxjs'; interface User { id: number; } class UserService { private _users$ = new BehaviorSubject([]) ...

Eliminate spacing in MaterialUi grids

As I work on a React project, I am faced with the task of displaying multiple cards with content on them. To achieve this layout, I have opted to use MaterialUi cards within Material UI grids. However, there seems to be an issue with excessive padding in t ...

Angular 4 in combination with ngx-datatable is showing a 404 error for the @swimlane/ngx-datatable package

Just starting out with Angular and I kicked things off by running this command: git clone https://github.com/angular/quickstart appName I've made the upgrade to Angular 4 and everything seems to be in order. Here's the output I got after running ...

The benefits of a modular design in a React and TypeScript library

Following a tutorial on creating a library with React, Typescript, and rollup, I successfully managed to get everything working. However, as my project grows with additional features, I'm looking to have modular exports similar to what is seen in redu ...

The battle of ng-bullet and karma-parallel: optimizing Angular unit test performance with test module configuration in before all block

I'm currently exploring different options to enhance the speed of my unit tests in an Angular project. After reading several blogs, I came across some suggestions: (1) ng-bullet (2) karma-paralle (3) ng test --browsers ChromeHeadless (4) configu ...

The error message "The file 'environment.ts' is not located within the specified 'rootDir' directory" was encountered during the Angular Library build process

When attempting to access the environment variable in an Angular 9 library, I encountered an error during the library build process. Here is how it was implemented: import { EnvironmentViewModel } from 'projects/falcon-core/src/lib/view-models/envir ...

Set Chartjs2 data to display as a doughnut chart starting from 0

When working with a doughnut chart and having data values set to 0, it is important to ensure that the default chart still displays with equal size parts. To achieve this, one can utilize the beginAtZero option in JavaScript: JS scales: { yAxes: [{ ...

What sets apart a search bar from a text field?

What distinguishes a searchbar from a textfield? Is there a way to eliminate the search icon in a searchbar? ...

What is the best way to employ document.addEventListener in TypeScript?

I am currently learning Ionic v2 and I am using document.addEventListener, but I am encountering errors as shown below: > [11:10:21] ionic-app-scripts 0.0.47 [11:10:21] build dev started ... [11:10:21] clean started ... [11:10:21] clean finished in ...

Can variables be declared for file paths within the HTML code in a TypeScript file?

We utilize the Vaadin designer to create the frontend of our project. Within the .ts files, we have images where we aim to establish variables for the file paths. Currently, the setup looks like this: <img src="../../themes/light/img/example.jpg&q ...