Select to view content in your preferred language

arcgis-features and mapimagelayer

149
6
Jump to solution
Wednesday
LefterisKoumis
Frequent Contributor

I use this script to display the popup in the arcgis-features.

I need to determine if the arcgis-features after it runs if it is empty or found features.

If i click on a featurelayer , then the console states that the component is not empty. 

However, if i click on a mapimagelayer it states that the component is empty even though there is a feature inside the arcgis-features. Why?

 const hitTestResult = await arcgisMap.view.hitTest(screenPoint);
    const mapPoint = arcgisMap.view.toMap(screenPoint);
    await arcgisFeatures.open({ 
      location: mapPoint, 
      features: results.map(r => r.graphic), // Include any client-side features found
      fetchFeatures: true 
    }).then((response) => {
      checkIfFeaturesEmpty()
    })
   

 

function checkIfFeaturesEmpty() {
  if (arcgisFeatures && arcgisFeatures.features) {
    if (arcgisFeatures.features.length === 0) {
      console.log('The <arcgis-features> component is empty.');
      return true;
    } else {
      console.log('The <arcgis-features> component is not empty and contains ' + arcgisFeatures.features.length + ' features.');
      return false;
    }
  } else {
    console.log('The <arcgis-features> element or its features property is not available yet.');
    return null; 
  }
}

 

0 Kudos
1 Solution

Accepted Solutions
Sage_Wall
Esri Regular Contributor

Hi @LefterisKoumis ,

I checked with our Features expert, and fetchFeatures will return the features for both MapImageLayer and FeatureLayer. This means you don’t need to manually set the features property in addition to enabling fetchFeatures.

The reason the features property appears empty when you test it with your checkIfFeaturesEmpty method is that the open method’s promise resolves when the Features component opens—not when it has finished fetching all features from the map point.


To handle this, set up a reactiveUtils.watch on the features property and then call your checkIfFeaturesEmpty function, similar to what’s demonstrated in this CodePen: 
https://codepen.io/sagewall/pen/JoKKJGz?editors=1000

viewElement.addEventListener("arcgisViewClick", (event) => {
        const {
            mapPoint
        } = event.detail;
        arcgisFeatures.open({
            location: mapPoint,
            fetchFeatures: true,
        });
    });
    reactiveUtils.watch(
        () => arcgisFeatures.features,
        () => {
            checkIfFeaturesEmpty()
        })

    function checkIfFeaturesEmpty() {
        if (arcgisFeatures && arcgisFeatures.features) {
            if (arcgisFeatures.features.length === 0) {
                console.log('The <arcgis-features> component is empty.');
                return true;
            } else {
                console.log('The <arcgis-features> component is not empty and contains ' + arcgisFeatures.features.length + ' features.');
                return false;
            }
        } else {
            console.log('The <arcgis-features> element or its features property is not available yet.');
            return null;
        }
    }

 
Kudos to @LaurenBoyd 

View solution in original post

0 Kudos
6 Replies
Sage_Wall
Esri Regular Contributor

Hi @LefterisKoumis ,  HitTest isn't supported for server based layers like MapImageLayer.  You will need to use identify with MapImageLayer.  This is a sample that shows how to use identify with a popup, the workflow isn't exactly the same with Features but it should be really similar.  If you have a mix of MapImageLayer and FeatureLayer you'll likely need to do a hit test and an identify to get all the results, or load the MapImageLayer sublayers as feature layers in the map.
https://developers.arcgis.com/javascript/latest/sample-code/identify/

I think the reason why your seeing the MapImageLayers in the Features component is because the fetchFeatures option for the open method likely sends both a hit test and identify.

0 Kudos
LefterisKoumis
Frequent Contributor

@Sage_Wall Are you suggesting to set the fetchFeatures to false and use the identify to collect the features from an mapimagelayer? If that's the case what is the use of the fetchFeatures?

    await arcgisFeatures.open({ 
      location: mapPoint, 
      features: [graphics]
      fetchFeatures: false
    })

 

For featurelayers we can use this and we don't need fetchFeatures.

arcgisFeatures.open({
  location: mapPoint,
  features: [graphics]
});

 

0 Kudos
Sage_Wall
Esri Regular Contributor

I’m not super familiar with the Features component, so apologies if I’m off base here, and I hope I'm not giving bad advice. My understanding is that fetchFeatures should retrieve all results from the mapPoint location—whether they come from a client-side FeatureLayer (or other client-side layers), or from a server-side MapImageLayer. I don’t think it’s necessary to define the features property when fetchFeatures is set to true. I haven't had a chance to test or experiment with this.

I’m guessing a bit about what’s in the results array you’re passing into the features property since that wasn’t included in the code snippets above, but I suspect it's only the results from a hit test. I’ll reach out to the Features PE and see if they can weigh in on this thread to get you an authoritative answer.

0 Kudos
Sage_Wall
Esri Regular Contributor

Hi @LefterisKoumis ,

I checked with our Features expert, and fetchFeatures will return the features for both MapImageLayer and FeatureLayer. This means you don’t need to manually set the features property in addition to enabling fetchFeatures.

The reason the features property appears empty when you test it with your checkIfFeaturesEmpty method is that the open method’s promise resolves when the Features component opens—not when it has finished fetching all features from the map point.


To handle this, set up a reactiveUtils.watch on the features property and then call your checkIfFeaturesEmpty function, similar to what’s demonstrated in this CodePen: 
https://codepen.io/sagewall/pen/JoKKJGz?editors=1000

viewElement.addEventListener("arcgisViewClick", (event) => {
        const {
            mapPoint
        } = event.detail;
        arcgisFeatures.open({
            location: mapPoint,
            fetchFeatures: true,
        });
    });
    reactiveUtils.watch(
        () => arcgisFeatures.features,
        () => {
            checkIfFeaturesEmpty()
        })

    function checkIfFeaturesEmpty() {
        if (arcgisFeatures && arcgisFeatures.features) {
            if (arcgisFeatures.features.length === 0) {
                console.log('The <arcgis-features> component is empty.');
                return true;
            } else {
                console.log('The <arcgis-features> component is not empty and contains ' + arcgisFeatures.features.length + ' features.');
                return false;
            }
        } else {
            console.log('The <arcgis-features> element or its features property is not available yet.');
            return null;
        }
    }

 
Kudos to @LaurenBoyd 

0 Kudos
LefterisKoumis
Frequent Contributor

Thank you so much @Sage_Wall and @LaurenBoyd . It makes sense since the fetchFeatures makes calls to the server and we have to wait until it retrieves the feature info. I think this is a good example to add to the documentation since I noticed that there are not many examples of using mapimagelayers with the web components.

LefterisKoumis
Frequent Contributor

I have an update @Sage_Wall and @LaurenBoyd.

I used the suggested script and I realized that sometimes the reactiveUtils.watch  is not triggered and sometimes it does. I don't what are reasons behind it. So, I modified to use the arcgisPropertyChange  property.

so instead of 

    reactiveUtils.watch(
        () => arcgisFeatures.features,
        () => {
            checkIfFeaturesEmpty()
        })

 

I use this

arcgisFeatures.addEventListener("arcgisPropertyChange", (event) => {
  if (arcgisFeatures.features.length>0) {
    checkIfFeaturesEmpty();
  }

 

0 Kudos