<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Implementing classBreakRenderer sends extra query req to feature layer in ArcGIS JavaScript Maps SDK Questions</title>
    <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-classbreakrenderer-sends-extra-query/m-p/1233241#M79384</link>
    <description>&lt;P&gt;I have upgraded the JavaScript API to 4.22 version from 4.5. The existing functionality of implementing classBreakRenderer using smart mapping is having performance issue.&lt;/P&gt;&lt;P&gt;I observed that there are extra 8-9 query requests sent to the server which my code has not created.&lt;/P&gt;&lt;P&gt;Here is step-wise implementation&lt;/P&gt;&lt;P&gt;API is integrated in ReactJS App&lt;/P&gt;&lt;P&gt;Here is the functionality implementation&lt;/P&gt;&lt;P&gt;I have put inline comment relevant to this post in blow code itself, starting with&amp;nbsp; //** Note&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const sellAccrualFeatureLayer = new FeatureLayer({
      url: '........../MapServer/4',
      id: 'sellAccrualFeatureLayer',
      outFields: ['*'],
      legendEnabled: true,
      visible: false
    })
    sellAccrualFeatureLayer.opacity = 0.5
    sellAccrualFeatureLayer.definitionExpression = '1=2'
    esrijs.map.add(sellAccrualFeatureLayer)
    esrijs.sellAccrualFeatureLayer = sellAccrualFeatureLayer&lt;/LI-CODE&gt;&lt;P&gt;Saved in esrijs variable and added to map with visible false.&lt;/P&gt;&lt;P&gt;2) On click of feature I have identify request to another layer to get the attribute of that feature and this acts as input where clause for sellAccrualFeatureLayer created in step 1&lt;/P&gt;&lt;P&gt;And here is the first query for sellAccrualFeatureLayer layer&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;makeQuerys = () =&amp;gt; {
    const sellAccrualFeatureLayer = esrijs.sellAccrualFeatureLayer
    const colorRendererCreator = window.require('esri/smartMapping/renderers/color')
    const legendContainer = this.legendContainer
    const map = esrijs.map
    const dispatch = this.props.dispatch
    const kauppapaikkaNro = this.props.selectedStore.feature.attributes.Kauppapaikkanro
    const queryTimeStamps = sellAccrualFeatureLayer.createQuery()
    queryTimeStamps.where = 'Kauppa=' + kauppapaikkaNro
    queryTimeStamps.spatialRelationship = 'intersects'
    queryTimeStamps.outFields = ['Aikaleima']
    queryTimeStamps.returnDistinctValues = true
    queryTimeStamps.returnGeometry = false
    queryTimeStamps.orderByFields = ['Aikaleima DESC']

    const colorSchemes = window.require('esri/smartMapping/symbology/color')

    const schemes = colorSchemes.getSchemes({
      basemap: map.basemap,
      geometryType: sellAccrualFeatureLayer.geometryType,
      theme: 'high-to-low'
    })

    // console.log(schemes)
    // console.log(schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/gray/seq-browns-bright'))
    sellAccrualFeatureLayer.queryFeatures(queryTimeStamps)
      .then(function (responseTimeStamps) {
        if (responseTimeStamps.features.length &amp;gt; 0 &amp;amp;&amp;amp; responseTimeStamps.features[0].attributes.Aikaleima) {
          const params = {
            layer: sellAccrualFeatureLayer,
            field: 'Kertyma',
            view: esrijs.view,
            classificationMethod: 'natural-breaks',
            numClasses: 4,
            legendOptions: {
              title: 'Kertymä'
            },
            // colorScheme: {...schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/' + schemes.basemapId + '/seq-browns-bright'), ...{opacity: 0.95}}
            colorScheme: {...schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/gray/seq-browns-bright'), ...{opacity: 0.95}}
          }

          // generate the renderer and set it on the layer
// ** Note this create renderer request to layer is executed within 1 sec so no issue here
          colorRendererCreator.createClassBreaksRenderer(params)
            .then(function (response) {
              const renderer = response.renderer
              renderer.defaultSymbol = null
              sellAccrualFeatureLayer.renderer = renderer

              if (!esrijs.legend || esrijs.legend.destroyed) {
                const Legend = window.require('esri/widgets/Legend')
                esrijs.legend = new Legend({
                  view: esrijs.view,
                  container: legendContainer
                })
              }
            }).catch(console.error)

          const timeStamps = responseTimeStamps.features.map(x =&amp;gt; x.attributes.Aikaleima)
          const latestTimestamp = timeStamps[0]
          const comparisonTimestamp = timeStamps.length &amp;gt; 1 ? timeStamps[1] : latestTimestamp

          const zipcodeWhere = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank &amp;lt;=40'
          sellAccrualFeatureLayer.definitionExpression = zipcodeWhere

          const queryZipcodeSellAccrual = sellAccrualFeatureLayer.createQuery()
          queryZipcodeSellAccrual.where = zipcodeWhere
          queryZipcodeSellAccrual.spatialRelationship = 'intersects'
          queryZipcodeSellAccrual.outFields = ['*']
          queryZipcodeSellAccrual.returnGeometry = false
          queryZipcodeSellAccrual.orderByFields = ['Rank']

// ** Note - observed from the Network tab, that when this below query is executed and req is sent, those extra query requests (PFA RankQueryreq.png are initiated and are in a pending state - and when these extra req are completed then only after that the req in the below Promise.All() are excuted, hence taking more time)

          sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrual)
            .then(function (responseZipcodeSellAccrual) {
              esrijs.sellAccrualFeatureLayer.visible = true
              const top40AccrualData = responseZipcodeSellAccrual.features.map(x =&amp;gt; x.attributes).reduce((acc, curr) =&amp;gt; {
                acc[curr.Postinumero] = true
                return acc
              }, {})
              const top40AccrualZipcodes = Object.keys(top40AccrualData)

              const queryZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
              queryZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank &amp;gt;40'
              queryZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
              queryZipcodeSellAccrualOver40.outFields = ['*']
              queryZipcodeSellAccrualOver40.returnGeometry = false
              queryZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40

              const queryComparisonZipcodeSellAccrualTop40 = sellAccrualFeatureLayer.createQuery()
              queryComparisonZipcodeSellAccrualTop40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
              queryComparisonZipcodeSellAccrualTop40.spatialRelationship = 'intersects'
              queryComparisonZipcodeSellAccrualTop40.outFields = ['*']
              queryComparisonZipcodeSellAccrualTop40.returnGeometry = false
              queryComparisonZipcodeSellAccrualTop40.orderByFields = ['Rank']

              const queryComparisonZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
              queryComparisonZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero NOT IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
              queryComparisonZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
              queryComparisonZipcodeSellAccrualOver40.outFields = ['*']
              queryComparisonZipcodeSellAccrualOver40.returnGeometry = false
              queryComparisonZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40

//** Note - These are the 3 req that start only after the extra req are completed

              Promise.all([
                sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrualOver40),
                sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualTop40),
                sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualOver40)
              ]).then(([currentAccrualSumOver40, comparisonAccrualTop40, comparisonAccrualSumOver40]) =&amp;gt; {
                console.log("after promise");
                const currentTop40Attributes = responseZipcodeSellAccrual.features.map(x =&amp;gt; x.attributes)
                const comparisonTop40Attributes = comparisonAccrualTop40.features.map(x =&amp;gt; x.attributes)

                const currentSumEurot = currentTop40Attributes.reduce((acc, curr) =&amp;gt; acc + curr.Eurot, currentAccrualSumOver40.features[0].attributes.SUMMA_Eurot)
                const comparisonSumEurot = comparisonTop40Attributes.reduce((acc, curr) =&amp;gt; acc + curr.Eurot, comparisonAccrualSumOver40.features[0].attributes.SUMMA_Eurot)

                const data = {
                  currentAccrualTop40: currentTop40Attributes.reduce((acc, curr) =&amp;gt; {
                    acc[curr.Postinumero] = calculateAdditionalFields(curr, currentSumEurot)
                    return acc
                  }, {}),
                  currentAccrualSumOver40: calculateAdditionalFields({
                    ...currentAccrualSumOver40.features[0].attributes,
                    usedTimestamp: latestTimestamp
                  }, currentSumEurot, true),
                  comparisonAccrualTop40: comparisonTop40Attributes.reduce((acc, curr) =&amp;gt; {
                    acc[curr.Postinumero] = calculateAdditionalFields(curr, comparisonSumEurot)
                    return acc
                  }, {}),
                  comparisonAccrualSumOver40: calculateAdditionalFields({
                    ...comparisonAccrualSumOver40.features[0].attributes,
                    usedTimestamp: comparisonTimestamp
                  }, comparisonSumEurot, true)
                }
                dispatch(setSellAccrualData(data))
              })
            }).catch(console.error)
        }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Attachment info&lt;/P&gt;&lt;P&gt;1) extraquery.png - Showing the extra req and req from promises&lt;/P&gt;&lt;P&gt;2) extraquerydetail.png - Details of one of the extra req&lt;/P&gt;&lt;P&gt;3)&amp;nbsp;queryreq.png&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried sending a list of outFields in all queries in the code, including in FeatureLayer Constructor - issue persists.&lt;/P&gt;&lt;P&gt;The issue is why it is sending extra req and those too for "ID" fields as orderby and this field is OID of that layer.&lt;/P&gt;&lt;P&gt;Will be grateful if anyone can help.&lt;/P&gt;</description>
    <pubDate>Fri, 18 Nov 2022 15:19:25 GMT</pubDate>
    <dc:creator>Mayur_Shinde</dc:creator>
    <dc:date>2022-11-18T15:19:25Z</dc:date>
    <item>
      <title>Implementing classBreakRenderer sends extra query req to feature layer</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-classbreakrenderer-sends-extra-query/m-p/1233241#M79384</link>
      <description>&lt;P&gt;I have upgraded the JavaScript API to 4.22 version from 4.5. The existing functionality of implementing classBreakRenderer using smart mapping is having performance issue.&lt;/P&gt;&lt;P&gt;I observed that there are extra 8-9 query requests sent to the server which my code has not created.&lt;/P&gt;&lt;P&gt;Here is step-wise implementation&lt;/P&gt;&lt;P&gt;API is integrated in ReactJS App&lt;/P&gt;&lt;P&gt;Here is the functionality implementation&lt;/P&gt;&lt;P&gt;I have put inline comment relevant to this post in blow code itself, starting with&amp;nbsp; //** Note&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const sellAccrualFeatureLayer = new FeatureLayer({
      url: '........../MapServer/4',
      id: 'sellAccrualFeatureLayer',
      outFields: ['*'],
      legendEnabled: true,
      visible: false
    })
    sellAccrualFeatureLayer.opacity = 0.5
    sellAccrualFeatureLayer.definitionExpression = '1=2'
    esrijs.map.add(sellAccrualFeatureLayer)
    esrijs.sellAccrualFeatureLayer = sellAccrualFeatureLayer&lt;/LI-CODE&gt;&lt;P&gt;Saved in esrijs variable and added to map with visible false.&lt;/P&gt;&lt;P&gt;2) On click of feature I have identify request to another layer to get the attribute of that feature and this acts as input where clause for sellAccrualFeatureLayer created in step 1&lt;/P&gt;&lt;P&gt;And here is the first query for sellAccrualFeatureLayer layer&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;makeQuerys = () =&amp;gt; {
    const sellAccrualFeatureLayer = esrijs.sellAccrualFeatureLayer
    const colorRendererCreator = window.require('esri/smartMapping/renderers/color')
    const legendContainer = this.legendContainer
    const map = esrijs.map
    const dispatch = this.props.dispatch
    const kauppapaikkaNro = this.props.selectedStore.feature.attributes.Kauppapaikkanro
    const queryTimeStamps = sellAccrualFeatureLayer.createQuery()
    queryTimeStamps.where = 'Kauppa=' + kauppapaikkaNro
    queryTimeStamps.spatialRelationship = 'intersects'
    queryTimeStamps.outFields = ['Aikaleima']
    queryTimeStamps.returnDistinctValues = true
    queryTimeStamps.returnGeometry = false
    queryTimeStamps.orderByFields = ['Aikaleima DESC']

    const colorSchemes = window.require('esri/smartMapping/symbology/color')

    const schemes = colorSchemes.getSchemes({
      basemap: map.basemap,
      geometryType: sellAccrualFeatureLayer.geometryType,
      theme: 'high-to-low'
    })

    // console.log(schemes)
    // console.log(schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/gray/seq-browns-bright'))
    sellAccrualFeatureLayer.queryFeatures(queryTimeStamps)
      .then(function (responseTimeStamps) {
        if (responseTimeStamps.features.length &amp;gt; 0 &amp;amp;&amp;amp; responseTimeStamps.features[0].attributes.Aikaleima) {
          const params = {
            layer: sellAccrualFeatureLayer,
            field: 'Kertyma',
            view: esrijs.view,
            classificationMethod: 'natural-breaks',
            numClasses: 4,
            legendOptions: {
              title: 'Kertymä'
            },
            // colorScheme: {...schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/' + schemes.basemapId + '/seq-browns-bright'), ...{opacity: 0.95}}
            colorScheme: {...schemes.secondarySchemes.find(sc =&amp;gt; sc.id === 'high-to-low/gray/seq-browns-bright'), ...{opacity: 0.95}}
          }

          // generate the renderer and set it on the layer
// ** Note this create renderer request to layer is executed within 1 sec so no issue here
          colorRendererCreator.createClassBreaksRenderer(params)
            .then(function (response) {
              const renderer = response.renderer
              renderer.defaultSymbol = null
              sellAccrualFeatureLayer.renderer = renderer

              if (!esrijs.legend || esrijs.legend.destroyed) {
                const Legend = window.require('esri/widgets/Legend')
                esrijs.legend = new Legend({
                  view: esrijs.view,
                  container: legendContainer
                })
              }
            }).catch(console.error)

          const timeStamps = responseTimeStamps.features.map(x =&amp;gt; x.attributes.Aikaleima)
          const latestTimestamp = timeStamps[0]
          const comparisonTimestamp = timeStamps.length &amp;gt; 1 ? timeStamps[1] : latestTimestamp

          const zipcodeWhere = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank &amp;lt;=40'
          sellAccrualFeatureLayer.definitionExpression = zipcodeWhere

          const queryZipcodeSellAccrual = sellAccrualFeatureLayer.createQuery()
          queryZipcodeSellAccrual.where = zipcodeWhere
          queryZipcodeSellAccrual.spatialRelationship = 'intersects'
          queryZipcodeSellAccrual.outFields = ['*']
          queryZipcodeSellAccrual.returnGeometry = false
          queryZipcodeSellAccrual.orderByFields = ['Rank']

// ** Note - observed from the Network tab, that when this below query is executed and req is sent, those extra query requests (PFA RankQueryreq.png are initiated and are in a pending state - and when these extra req are completed then only after that the req in the below Promise.All() are excuted, hence taking more time)

          sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrual)
            .then(function (responseZipcodeSellAccrual) {
              esrijs.sellAccrualFeatureLayer.visible = true
              const top40AccrualData = responseZipcodeSellAccrual.features.map(x =&amp;gt; x.attributes).reduce((acc, curr) =&amp;gt; {
                acc[curr.Postinumero] = true
                return acc
              }, {})
              const top40AccrualZipcodes = Object.keys(top40AccrualData)

              const queryZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
              queryZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank &amp;gt;40'
              queryZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
              queryZipcodeSellAccrualOver40.outFields = ['*']
              queryZipcodeSellAccrualOver40.returnGeometry = false
              queryZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40

              const queryComparisonZipcodeSellAccrualTop40 = sellAccrualFeatureLayer.createQuery()
              queryComparisonZipcodeSellAccrualTop40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
              queryComparisonZipcodeSellAccrualTop40.spatialRelationship = 'intersects'
              queryComparisonZipcodeSellAccrualTop40.outFields = ['*']
              queryComparisonZipcodeSellAccrualTop40.returnGeometry = false
              queryComparisonZipcodeSellAccrualTop40.orderByFields = ['Rank']

              const queryComparisonZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
              queryComparisonZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero NOT IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
              queryComparisonZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
              queryComparisonZipcodeSellAccrualOver40.outFields = ['*']
              queryComparisonZipcodeSellAccrualOver40.returnGeometry = false
              queryComparisonZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40

//** Note - These are the 3 req that start only after the extra req are completed

              Promise.all([
                sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrualOver40),
                sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualTop40),
                sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualOver40)
              ]).then(([currentAccrualSumOver40, comparisonAccrualTop40, comparisonAccrualSumOver40]) =&amp;gt; {
                console.log("after promise");
                const currentTop40Attributes = responseZipcodeSellAccrual.features.map(x =&amp;gt; x.attributes)
                const comparisonTop40Attributes = comparisonAccrualTop40.features.map(x =&amp;gt; x.attributes)

                const currentSumEurot = currentTop40Attributes.reduce((acc, curr) =&amp;gt; acc + curr.Eurot, currentAccrualSumOver40.features[0].attributes.SUMMA_Eurot)
                const comparisonSumEurot = comparisonTop40Attributes.reduce((acc, curr) =&amp;gt; acc + curr.Eurot, comparisonAccrualSumOver40.features[0].attributes.SUMMA_Eurot)

                const data = {
                  currentAccrualTop40: currentTop40Attributes.reduce((acc, curr) =&amp;gt; {
                    acc[curr.Postinumero] = calculateAdditionalFields(curr, currentSumEurot)
                    return acc
                  }, {}),
                  currentAccrualSumOver40: calculateAdditionalFields({
                    ...currentAccrualSumOver40.features[0].attributes,
                    usedTimestamp: latestTimestamp
                  }, currentSumEurot, true),
                  comparisonAccrualTop40: comparisonTop40Attributes.reduce((acc, curr) =&amp;gt; {
                    acc[curr.Postinumero] = calculateAdditionalFields(curr, comparisonSumEurot)
                    return acc
                  }, {}),
                  comparisonAccrualSumOver40: calculateAdditionalFields({
                    ...comparisonAccrualSumOver40.features[0].attributes,
                    usedTimestamp: comparisonTimestamp
                  }, comparisonSumEurot, true)
                }
                dispatch(setSellAccrualData(data))
              })
            }).catch(console.error)
        }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Attachment info&lt;/P&gt;&lt;P&gt;1) extraquery.png - Showing the extra req and req from promises&lt;/P&gt;&lt;P&gt;2) extraquerydetail.png - Details of one of the extra req&lt;/P&gt;&lt;P&gt;3)&amp;nbsp;queryreq.png&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried sending a list of outFields in all queries in the code, including in FeatureLayer Constructor - issue persists.&lt;/P&gt;&lt;P&gt;The issue is why it is sending extra req and those too for "ID" fields as orderby and this field is OID of that layer.&lt;/P&gt;&lt;P&gt;Will be grateful if anyone can help.&lt;/P&gt;</description>
      <pubDate>Fri, 18 Nov 2022 15:19:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-classbreakrenderer-sends-extra-query/m-p/1233241#M79384</guid>
      <dc:creator>Mayur_Shinde</dc:creator>
      <dc:date>2022-11-18T15:19:25Z</dc:date>
    </item>
  </channel>
</rss>

