@@ -13,6 +13,7 @@ import {
1313 FEATURE_ID_PROPERTY_NAME ,
1414 SOURCE_DATA_ID_ORIGIN ,
1515 SOURCE_META_ID_ORIGIN ,
16+ SOURCE_FORMATTERS_ID_ORIGIN ,
1617 FEATURE_VISIBLE_PROPERTY_NAME ,
1718 EMPTY_FEATURE_COLLECTION ,
1819 LAYER_TYPE ,
@@ -24,7 +25,11 @@ import { JoinTooltipProperty } from './tooltips/join_tooltip_property';
2425import { EuiIcon } from '@elastic/eui' ;
2526import { i18n } from '@kbn/i18n' ;
2627import { DataRequestAbortError } from './util/data_request' ;
27- import { canSkipSourceUpdate , canSkipStyleMetaUpdate } from './util/can_skip_fetch' ;
28+ import {
29+ canSkipSourceUpdate ,
30+ canSkipStyleMetaUpdate ,
31+ canSkipFormattersUpdate ,
32+ } from './util/can_skip_fetch' ;
2833import { assignFeatureIds } from './util/assign_feature_ids' ;
2934import {
3035 getFillFilterExpression ,
@@ -220,7 +225,7 @@ export class VectorLayer extends AbstractLayer {
220225 return indexPatternIds ;
221226 }
222227
223- _findDataRequestForSource ( sourceDataId ) {
228+ _findDataRequestById ( sourceDataId ) {
224229 return this . _dataRequests . find ( dataRequest => dataRequest . getDataId ( ) === sourceDataId ) ;
225230 }
226231
@@ -241,7 +246,7 @@ export class VectorLayer extends AbstractLayer {
241246 sourceQuery : joinSource . getWhereQuery ( ) ,
242247 applyGlobalQuery : joinSource . getApplyGlobalQuery ( ) ,
243248 } ;
244- const prevDataRequest = this . _findDataRequestForSource ( sourceDataId ) ;
249+ const prevDataRequest = this . _findDataRequestById ( sourceDataId ) ;
245250
246251 const canSkipFetch = await canSkipSourceUpdate ( {
247252 source : joinSource ,
@@ -286,6 +291,7 @@ export class VectorLayer extends AbstractLayer {
286291 async _syncJoins ( syncContext ) {
287292 const joinSyncs = this . getValidJoins ( ) . map ( async join => {
288293 await this . _syncJoinStyleMeta ( syncContext , join ) ;
294+ await this . _syncJoinFormatters ( syncContext , join ) ;
289295 return this . _syncJoin ( { join, ...syncContext } ) ;
290296 } ) ;
291297
@@ -355,7 +361,7 @@ export class VectorLayer extends AbstractLayer {
355361 registerCancelCallback,
356362 dataFilters,
357363 } ) {
358- const requestToken = Symbol ( `layer-source-data: ${ this . getId ( ) } ` ) ;
364+ const requestToken = Symbol ( `layer-${ this . getId ( ) } - ${ SOURCE_DATA_ID_ORIGIN } ` ) ;
359365 const searchFilters = this . _getSearchFilters ( dataFilters ) ;
360366 const prevDataRequest = this . getSourceDataRequest ( ) ;
361367
@@ -459,13 +465,13 @@ export class VectorLayer extends AbstractLayer {
459465 isTimeAware : this . _style . isTimeAware ( ) && ( await source . isTimeAware ( ) ) ,
460466 timeFilters : dataFilters . timeFilters ,
461467 } ;
462- const prevDataRequest = this . _findDataRequestForSource ( dataRequestId ) ;
468+ const prevDataRequest = this . _findDataRequestById ( dataRequestId ) ;
463469 const canSkipFetch = canSkipStyleMetaUpdate ( { prevDataRequest, nextMeta } ) ;
464470 if ( canSkipFetch ) {
465471 return ;
466472 }
467473
468- const requestToken = Symbol ( `layer-${ this . getId ( ) } -style-meta ` ) ;
474+ const requestToken = Symbol ( `layer-${ this . getId ( ) } -${ dataRequestId } ` ) ;
469475 try {
470476 startLoading ( dataRequestId , requestToken , nextMeta ) ;
471477 const layerName = await this . getDisplayName ( ) ;
@@ -484,12 +490,87 @@ export class VectorLayer extends AbstractLayer {
484490 }
485491 }
486492
493+ async _syncSourceFormatters ( syncContext ) {
494+ if ( this . _style . constructor . type !== LAYER_STYLE_TYPE . VECTOR ) {
495+ return ;
496+ }
497+
498+ return this . _syncFormatters ( {
499+ source : this . _source ,
500+ dataRequestId : SOURCE_FORMATTERS_ID_ORIGIN ,
501+ fields : this . _style
502+ . getDynamicPropertiesArray ( )
503+ . filter ( dynamicStyleProp => {
504+ return dynamicStyleProp . getFieldOrigin ( ) === FIELD_ORIGIN . SOURCE ;
505+ } )
506+ . map ( dynamicStyleProp => {
507+ return dynamicStyleProp . getField ( ) ;
508+ } ) ,
509+ ...syncContext ,
510+ } ) ;
511+ }
512+
513+ async _syncJoinFormatters ( syncContext , join ) {
514+ const joinSource = join . getRightJoinSource ( ) ;
515+ return this . _syncFormatters ( {
516+ source : joinSource ,
517+ dataRequestId : join . getSourceFormattersDataRequestId ( ) ,
518+ fields : this . _style
519+ . getDynamicPropertiesArray ( )
520+ . filter ( dynamicStyleProp => {
521+ const matchingField = joinSource . getMetricFieldForName (
522+ dynamicStyleProp . getField ( ) . getName ( )
523+ ) ;
524+ return dynamicStyleProp . getFieldOrigin ( ) === FIELD_ORIGIN . JOIN && ! ! matchingField ;
525+ } )
526+ . map ( dynamicStyleProp => {
527+ return dynamicStyleProp . getField ( ) ;
528+ } ) ,
529+ ...syncContext ,
530+ } ) ;
531+ }
532+
533+ async _syncFormatters ( { source, dataRequestId, fields, startLoading, stopLoading, onLoadError } ) {
534+ if ( fields . length === 0 ) {
535+ return ;
536+ }
537+
538+ const fieldNames = fields . map ( field => {
539+ return field . getName ( ) ;
540+ } ) ;
541+ const nextMeta = {
542+ fieldNames : _ . uniq ( fieldNames ) . sort ( ) ,
543+ } ;
544+ const prevDataRequest = this . _findDataRequestById ( dataRequestId ) ;
545+ const canSkipUpdate = canSkipFormattersUpdate ( { prevDataRequest, nextMeta } ) ;
546+ if ( canSkipUpdate ) {
547+ return ;
548+ }
549+
550+ const requestToken = Symbol ( `layer-${ this . getId ( ) } -${ dataRequestId } ` ) ;
551+ try {
552+ startLoading ( dataRequestId , requestToken , nextMeta ) ;
553+
554+ const formatters = { } ;
555+ const promises = fields . map ( async field => {
556+ const fieldName = field . getName ( ) ;
557+ formatters [ fieldName ] = await source . getFieldFormatter ( fieldName ) ;
558+ } ) ;
559+ await Promise . all ( promises ) ;
560+
561+ stopLoading ( dataRequestId , requestToken , formatters , nextMeta ) ;
562+ } catch ( error ) {
563+ onLoadError ( dataRequestId , requestToken , error . message ) ;
564+ }
565+ }
566+
487567 async syncData ( syncContext ) {
488568 if ( ! this . isVisible ( ) || ! this . showAtZoomLevel ( syncContext . dataFilters . zoom ) ) {
489569 return ;
490570 }
491571
492572 await this . _syncSourceStyleMeta ( syncContext ) ;
573+ await this . _syncSourceFormatters ( syncContext ) ;
493574 const sourceResult = await this . _syncSource ( syncContext ) ;
494575 if (
495576 ! sourceResult . featureCollection ||
0 commit comments