fieldMapping doesn't work as expected

Hello, here is problem:


I've created my own adaptor to get data from remote server using my API client, so I appliacated remoteData to dataSourceSettings and I get data everytime I need. The problem is with empty fields, I have list of these fields and manually insert them in index 0 with undefiend value to make sure they'll be shown. 

It's not right way to do add some fields, not only because it's "dirty code", but also I have no idea how to applicate other properties, I tried fieldMapping many times and it just ignores this property, I tried to do it manually and it's ignored as well.


I just need to know how to map my fields to table, show it in fieldList even when there's no data.


Here are parts of my code:

      const remoteData =
         new DataManager({
           adaptor: new CustomDataAdaptor({
             getData (option: FetchOption) {
               console.log(option);
               const params = option?.data;
               GetPivotData.dispatch(1074, 5089, params)
                 .then((data) => {
                   const result = {
                     ...Object.fromEntries(loadData.fieldMetadatas.map(name => [name.fieldKey, undefined])),
                   };
                   option?.onSuccess?.([{ ...result, ...data[0] }, ...data.slice(1)]);
                 }).catch((error) => {
                   option?.onFailure?.(error);
                 });
             },
           }),
           offline: false,
         });

      const dataSourceSettings : IDataOptions =
         {
           enableSorting: true,
           dataSource: remoteData,
           expandAll: false,
           fieldMapping: loadData.fieldMetadatas.map(field => ({
             name: field.fieldKey,
             caption: field.label || field.fieldKey,
             showNoDataItems: true,
           }))
         };




1 Reply

SK Sridhar Karunakaran Syncfusion Team June 3, 2025 02:13 PM UTC

Hi Nikita,


Thank you for sharing the code example. We apologize for not fully understanding your exact requirements from your initial query. However, based on your explanation, we understand that you want to insert new fields at the first index of the data source with undefined values, where these fields are not currently present in the data source.


If our understanding is correct, we have verified your requirement using the provided code example. We successfully added fields with undefined values to the first object in the data source. Additionally, we were able to specify the caption and dataType for fields not bound to the report settings using the fieldMapping option.


Furthermore, we confirm that inserting fields at the first index of the data source before rendering the Pivot Table—along with defining the caption and dataType for unbound fields via fieldMapping—is the correct approach. Please refer to the code example below for reference:


Code example:

import React, { useMemo } from "react";

import { DataManager, WebApiAdaptor, Query, CustomDataAdaptor, FetchOption } from "@syncfusion/ej2-data";

 

// Define your field metadata type

interface FieldMetadata {

  fieldKey: string;

  label?: string;

  dataType?: string;

}

 

// Mock your loadData with field metadata

const loadData = {

  fieldMetadatas: [

    { fieldKey: "Date_Y", label: "Year" },

    { fieldKey: "Date_Q", label: "Quarter" },

    { fieldKey: "Date_M", label: "Month" },

    { fieldKey: "State", label: "Status" },

    { fieldKey: "TotalCosts", label: "Total Costs", dataType: "number" },

    { fieldKey: "TotalRevenue", label: "Total Revenue", dataType: "number" },

    { fieldKey: "Profit", label: "Net Profit", dataType: "number" },

    { fieldKey: "rank_display", label: "Rank", dataType: "number" },

    { fieldKey: "country", label: "Country" },

    { fieldKey: "city", label: "City" },

    { fieldKey: "region", label: "Region" },

    { fieldKey: "research_output", label: "Research Output", dataType: "number" },

    { fieldKey: "student_faculty_ratio", label: "Student Faculty Ratio", dataType: "number" }

  ] as FieldMetadata[]

};


// Mock GetPivotData function to simulate API call

const GetPivotData = {

  dispatch: async (domainId: number, processId: number, params?: any) => {

    try {

      // Simulate API delay

      await new Promise(resolve => setTimeout(resolve, 500));

      // Mock data - in real implementation this would come from your API

      const mockData: any = [

        {

          Date_Y: "2023",

          Date_Q: "Q2",

          State: "Approved",

          TotalCosts: 7500,

          TotalRevenue: 15000,

          Profit: 7500,

          country: "Country1"

        }

      ];

      return mockData;

    } catch (error) {

      console.error("Error fetching data:", error);

      throw error;

    }

  }

};

// React Component

const PivotTable: React.FC = () => {

  const remoteData = useMemo(() => {

    return new DataManager({

      adaptor: new CustomDataAdaptor({

        async getData(option: FetchOption) {

          try {

            debugger

            const params = option?.data;

            const data = await GetPivotData.dispatch(1074, 5089, params);

            const result = {

              ...Object.fromEntries(loadData.fieldMetadatas.map(name => [name.fieldKey, undefined])),

            };

            option?.onSuccess?.([{ ...result, ...data[0] }, ...data.slice(1)]);

          } catch (error) {

            option?.onFailure?.(error);

          }

        },

      }),

      offline: false,

    });

  }, []);

 

  // Customer's dataSourceSettings (retained exactly as provided)

  const dataSourceSettings = useMemo((): IDataOptions => {

    return {

      // Field mapping with showNoDataItems set to true for all fields

      fieldMapping: loadData.fieldMetadatas.map(field => ({

        name: field.fieldKey,

        caption: field.label || field.fieldKey,

        dataType: field.dataType as any || "string",

        showNoDataItems: true // This ensures fields appear even with no data

      })),

    };

  }, [remoteData]);

 

  return (

    <PivotViewComponent dataSourceSettings={dataSourceSettings} showFieldList={true}>

      <Inject services={[FieldList]} />

    </PivotViewComponent>

  );

};

 

Output screenshot:

Additionally, we would like to inform you that the fieldMapping property is intended solely for specifying the caption, data type, and other configurations for fields that are not yet defined or bound in the report settings (i.e., rows, columns, values, and filters). When such fields are dynamically added to any axis of the Pivot Table, the component processes them using the information provided in fieldMapping.


If you wish to configure the caption, data type, or aggregation type for a field that is already included in the report settings, you must define these settings directly within the corresponding axis configuration (e.g., within rows, columns, values, or filters). This is the expected and current behavior of the Pivot Table.


For more details about the fieldMapping property and its use cases, please refer to the following documentation:

Documentation: https://ej2.syncfusion.com/react/documentation/pivotview/data-binding#mapping


However, if the above information does not match your requirements, please provide more detailed information about your needs. If possible, include a screenshot or video that illustrates your requirement. This will help us investigate further and provide you with the appropriate solution as quickly as possible.


Regards,

Sridhar Karunakaran.


Attachment: Sample_79e62a94.zip

Loader.
Up arrow icon