diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md
index 1a0a08f44451a..ac8ddce6e7016 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformatsstart.md
@@ -8,7 +8,7 @@
Signature:
```typescript
-export declare type FieldFormatsStart = Omit & {
+export declare type FieldFormatsStart = Omit & {
deserialize: FormatFactory;
};
```
diff --git a/src/plugins/data/common/field_formats/field_formats_registry.test.ts b/src/plugins/data/common/field_formats/field_formats_registry.test.ts
index 5e9866787f81c..86e44b69c05bf 100644
--- a/src/plugins/data/common/field_formats/field_formats_registry.test.ts
+++ b/src/plugins/data/common/field_formats/field_formats_registry.test.ts
@@ -76,6 +76,27 @@ describe('FieldFormatsRegistry', () => {
expect(registeredFieldFormatters.get(StringFormat.id)).toBe(StringFormat);
expect(registeredFieldFormatters.get(PercentFormat.id)).toBeUndefined();
});
+
+ test('should throw if registering a formatter with existing id ', () => {
+ fieldFormatsRegistry.register([BoolFormat]);
+
+ expect(() => fieldFormatsRegistry.register([BoolFormat])).toThrowErrorMatchingInlineSnapshot(
+ `"Failed to register field format with id \\"boolean\\" as it already has been registered"`
+ );
+ });
+ });
+
+ describe('has', () => {
+ test('should provide an public "has" method', () => {
+ expect(fieldFormatsRegistry.has).toBeDefined();
+ expect(typeof fieldFormatsRegistry.has).toBe('function');
+ });
+
+ test('should check if field format registered', () => {
+ fieldFormatsRegistry.register([StringFormat]);
+ expect(fieldFormatsRegistry.has(StringFormat.id)).toBe(true);
+ expect(fieldFormatsRegistry.has(BoolFormat.id)).toBe(false);
+ });
});
describe('getType', () => {
diff --git a/src/plugins/data/common/field_formats/field_formats_registry.ts b/src/plugins/data/common/field_formats/field_formats_registry.ts
index 6ee4d15aab042..58660f5856923 100644
--- a/src/plugins/data/common/field_formats/field_formats_registry.ts
+++ b/src/plugins/data/common/field_formats/field_formats_registry.ts
@@ -253,7 +253,21 @@ export class FieldFormatsRegistry {
}
register(fieldFormats: FieldFormatInstanceType[]) {
- fieldFormats.forEach((fieldFormat) => this.fieldFormats.set(fieldFormat.id, fieldFormat));
+ fieldFormats.forEach((fieldFormat) => {
+ if (this.fieldFormats.has(fieldFormat.id))
+ throw new Error(
+ `Failed to register field format with id "${fieldFormat.id}" as it already has been registered`
+ );
+ this.fieldFormats.set(fieldFormat.id, fieldFormat);
+ });
+ }
+
+ /**
+ * Checks if field format with id already registered
+ * @param id
+ */
+ has(id: string): boolean {
+ return this.fieldFormats.has(id);
}
/**
diff --git a/src/plugins/data/common/field_formats/mocks.ts b/src/plugins/data/common/field_formats/mocks.ts
index b027e021dea68..fa56afb2c277c 100644
--- a/src/plugins/data/common/field_formats/mocks.ts
+++ b/src/plugins/data/common/field_formats/mocks.ts
@@ -25,6 +25,7 @@ export const fieldFormatsMock: IFieldFormatsRegistry = {
getTypeNameByEsTypes: jest.fn(),
init: jest.fn(),
register: jest.fn(),
+ has: jest.fn(),
parseDefaultTypeMap: jest.fn(),
deserialize: jest.fn().mockImplementation(() => {
const DefaultFieldFormat = FieldFormat.from(identity);
diff --git a/src/plugins/data/common/field_formats/types.ts b/src/plugins/data/common/field_formats/types.ts
index 017dca1969fe7..b1d290388a42b 100644
--- a/src/plugins/data/common/field_formats/types.ts
+++ b/src/plugins/data/common/field_formats/types.ts
@@ -94,4 +94,4 @@ export interface IFieldFormatMetaParams {
};
}
-export type FieldFormatsStartCommon = Omit;
+export type FieldFormatsStartCommon = Omit;
diff --git a/src/plugins/data/public/field_formats/field_formats_service.ts b/src/plugins/data/public/field_formats/field_formats_service.ts
index 4edea8788328d..89b3bf2249315 100644
--- a/src/plugins/data/public/field_formats/field_formats_service.ts
+++ b/src/plugins/data/public/field_formats/field_formats_service.ts
@@ -49,9 +49,9 @@ export class FieldFormatsService {
}
/** @public */
-export type FieldFormatsSetup = Pick;
+export type FieldFormatsSetup = Pick;
/** @public */
-export type FieldFormatsStart = Omit & {
+export type FieldFormatsStart = Omit & {
deserialize: FormatFactory;
};
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index 8ec5eeca70b06..d065cedce36b3 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -1069,7 +1069,7 @@ export type FieldFormatsContentType = 'html' | 'text';
export type FieldFormatsGetConfigFn = GetConfigFn;
// @public (undocumented)
-export type FieldFormatsStart = Omit & {
+export type FieldFormatsStart = Omit & {
deserialize: FormatFactory;
};
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts
index 35afd28c0f1ab..b5844fa5cf4d6 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts
@@ -35,7 +35,7 @@ export class IndexPatternDatasource {
setup(
core: CoreSetup,
- { expressions, editorFrame, charts }: IndexPatternDatasourceSetupPlugins
+ { expressions, editorFrame, charts, data: dataSetup }: IndexPatternDatasourceSetupPlugins
) {
editorFrame.registerDatasource(async () => {
const {
@@ -48,8 +48,11 @@ export class IndexPatternDatasource {
} = await import('../async_services');
return core
.getStartServices()
- .then(([coreStart, { data, indexPatternFieldEditor, uiActions }]) => {
- data.fieldFormats.register([getSuffixFormatter(data.fieldFormats.deserialize)]);
+ .then(([coreStart, { indexPatternFieldEditor, uiActions, data }]) => {
+ const suffixFormatter = getSuffixFormatter(data.fieldFormats.deserialize);
+ if (!dataSetup.fieldFormats.has(suffixFormatter.id)) {
+ dataSetup.fieldFormats.register([suffixFormatter]);
+ }
expressions.registerFunction(timeScale);
expressions.registerFunction(counterRate);
expressions.registerFunction(renameColumns);