Filter features before loading

1565
6
Jump to solution
09-10-2020 11:11 AM
MarkC1
by
Occasional Contributor

I want to filter features based on the user that is logged in. This should be invisible to the user and require no user interaction or on screen widget. Similar questions have been asked before but I haven't had any success trying to implement this.

Run Filter in background executing programmatically an expession 

Filtering a webmap layer within a web appbuilder application on startup 

The answer seems to be to use the filter manager class: FilterManager class—ArcGIS Web AppBuilder (Developer Edition) | ArcGIS for Developers 

, and to use this method applyWidgetFilter (layerId, widgetId, expression) somewhere in the MapManager.js file 

 

I've been struggling to apply this however and haven't been able to get it to work. Has anyone any experience here that they could guide me?

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Mark,

  In the MapManager.js _show2DWebMap method (see line 46). 

...
        mapDeferred.then(lang.hitch(this, function(response) {
          var map = response.map;

          //hide the default zoom slider
          map.hideZoomSlider();

          // set default size of infoWindow.
          map.infoWindow.resize(270, 316);
          //var extent;
          map.itemId = appConfig.map.itemId;
          map.itemInfo = response.itemInfo;
          map.webMapResponse = response;
          // enable snapping
          var options = {
            snapKey: keys.copyKey
          };
          map.enableSnapping(options);

          html.setStyle(map.root, 'zIndex', 0);

          map._initialExtent = map.extent;

          this.layerInfosObj = LayerInfos.getInstanceSyncForInit(map, map.itemInfo);

          //save layer's original refreshInterval
          this.layerInfosObj.getLayerInfoArrayOfWebmap().forEach(function(layerInfo) {
            layerInfo.getLayerObject().then(lang.hitch(this, function(layerObject){
              if(layerObject){
                lang.setObject("_wabProperties.originalRefreshinterval", layerObject.refreshInterval, layerObject);
              }
            }), lang.hitch(this, function(err){
              console.error("can't get layerObject", err);
            }));
          }, this);

          if(appConfig.map.mapRefreshInterval && !appConfig.map.mapRefreshInterval.useWebMapRefreshInterval){
            this._updateRefreshInterval(appConfig.map.mapRefreshInterval);
          }

          this._showUnreachableLayersTitleMessage();
          this._publishMapEvent(map);
          setTimeout(lang.hitch(this, this._checkAppState), 500);
          this._addDataLoadingOnMapUpdate(map);
          this._hideError();
          this.filterManager.applyWidgetFilter('LOJIC_PublicSafety_Louisville_8690', null, "PD_NAME LIKE '% DIVISION'");
        }), lang.hitch(this, function(error) {
          console.error(error);
          this._showError(error);
          topic.publish('mapCreatedFailed');
        }));

View solution in original post

6 Replies
RobertScheitlin__GISP
MVP Emeritus

Mark,

  In the MapManager.js _show2DWebMap method (see line 46). 

...
        mapDeferred.then(lang.hitch(this, function(response) {
          var map = response.map;

          //hide the default zoom slider
          map.hideZoomSlider();

          // set default size of infoWindow.
          map.infoWindow.resize(270, 316);
          //var extent;
          map.itemId = appConfig.map.itemId;
          map.itemInfo = response.itemInfo;
          map.webMapResponse = response;
          // enable snapping
          var options = {
            snapKey: keys.copyKey
          };
          map.enableSnapping(options);

          html.setStyle(map.root, 'zIndex', 0);

          map._initialExtent = map.extent;

          this.layerInfosObj = LayerInfos.getInstanceSyncForInit(map, map.itemInfo);

          //save layer's original refreshInterval
          this.layerInfosObj.getLayerInfoArrayOfWebmap().forEach(function(layerInfo) {
            layerInfo.getLayerObject().then(lang.hitch(this, function(layerObject){
              if(layerObject){
                lang.setObject("_wabProperties.originalRefreshinterval", layerObject.refreshInterval, layerObject);
              }
            }), lang.hitch(this, function(err){
              console.error("can't get layerObject", err);
            }));
          }, this);

          if(appConfig.map.mapRefreshInterval && !appConfig.map.mapRefreshInterval.useWebMapRefreshInterval){
            this._updateRefreshInterval(appConfig.map.mapRefreshInterval);
          }

          this._showUnreachableLayersTitleMessage();
          this._publishMapEvent(map);
          setTimeout(lang.hitch(this, this._checkAppState), 500);
          this._addDataLoadingOnMapUpdate(map);
          this._hideError();
          this.filterManager.applyWidgetFilter('LOJIC_PublicSafety_Louisville_8690', null, "PD_NAME LIKE '% DIVISION'");
        }), lang.hitch(this, function(error) {
          console.error(error);
          this._showError(error);
          topic.publish('mapCreatedFailed');
        }));
MarkC1
by
Occasional Contributor

That's it Robert! I had my line in the _show2DMap method but in the wrong place. 

Thanks very much for your help, much appreciated!

0 Kudos
MarkC1
by
Occasional Contributor

Robert, I'm having a little bit of an undesired effect with this. Depending on the webmap/layers I use in the webapp, the full layer will briefly be visible before the filter is applied. Is there any way to prevent this?

I'd imagine applying a server-side filter by setting the Feature Layer "definition expression" as described in the Javascript API documentation here would be what I need but is it possible to do this in a Web AppBuilder App? Any ideas?

Filter a feature layer | ArcGIS API for JavaScript 4.16 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Mark,

   You can do the filter in the Web Map that your WAB uses in AGOL/Portal then it will be filtered before it even reaches WAB.

0 Kudos
MarkC1
by
Occasional Contributor

Hi Robert

I'm filtering the layer based on the logged in user (from my own authentication system) in a web app so can't filter the web map in advance like that unfortunately. Has to be done at runtime. I can build an app from scratch in JS but was hoping I could save a lot of work by modifying a web appbuilder app as this is only a short term app.

I think my workaround will be to have all layers turned off, filter my data as above and then make the layer visible.

It's just odd that it's happening with these one specific webmap. With other webmaps I've tested this with I don't see this behaviour, I only ever see the filtered features. Anyway, thanks for your help.

jauhari_mani
Occasional Contributor

Hi @RobertScheitlin__GISP,

Is there a way to drop some layers from web Map based on the user logged in filter is one way remove the data from the layer data but is it possible to drop layers from layer list.

Mani