Select to view content in your preferred language

Unable to refresh Feature Layer and see symbology change

605
3
12-06-2022 02:54 PM
rhughes522
Occasional Contributor

Using the jsapi 4.24 in the Dev ExB v1.9.0.

In a custom widget I am editing a hosted Feature Layer - success

Then I need to refresh the layer in the MapView.  I call layer.refresh(), and when I view the on("refresh") event properties it does say dataUpdated.  However, the graphics don't change in the LayerView.  The only way I can get the graphics to change is by zooming in/out.

Before I try to remove and re-add the layers, i am interested in finding out if this FeatureLayer.refresh() method is supposed to also update the Feature Layer View.  Based on the comments in the searches online I think it should.

Does Experience Builder have it's own FeatureLayer refresh() method that I need to use instead?  

I'd really like to update the LayerView graphics without needing to change the map zoom level.

0 Kudos
3 Replies
rhughes522
Occasional Contributor

i am doing some cleanup with the Promises that are running before the refresh() to make sure all the editing has completed.  I think it's possible that not all the edit calls completed before the refresh() gets run.

0 Kudos
rhughes522
Occasional Contributor

No change after implementing Promise.all() on the list of promises resolved after each applyEdits.  The edited feature oids (update only) are successfully returned by the Promise before I run the refresh() method. I will try and post my widget code.

performUpdate = (envelope_layer: FeatureLayer, turbine_layer: FeatureLayer, queryParams: Query, is_base_case: number) => {
    const promise1 = new Promise((resolve, reject) => {
      envelope_layer.queryFeatures(queryParams).then(function(result) {
        console.log(result.features);
        // set is_base_case to false on each features and collect object ids
        const oids = [];
        result.features.forEach(element => {
          element.attributes["is_base_case"] = is_base_case;
          oids.push(element.attributes["objectid"]);
        });
        // edit the layer with the updated features
        envelope_layer.applyEdits({
          updateFeatures: result.features
        }).then(function() {
          // query the related turbine features and update is_base_case
          const rel_query = {
            outFields: ["*"],
            relationshipId: 0,
            objectIds: oids
          }

          envelope_layer.queryRelatedFeatures(rel_query).then(function(result) {
            let promises = [];
            oids.forEach(oid => {
              const prom = new Promise((resolve2, reject2) => {
                if (result[oid]) {
                  console.group("relationship for feature:", oid);
                  const turbine_feats = result[oid].features;
                  // set the is_base_case on features to false
                  turbine_feats.forEach(feat => {
                    console.log("attributes", JSON.stringify(feat.attributes));
                    feat.attributes["is_base_case"] = is_base_case;
                  });
                  // edit the turbine layer with the updated turbine features
                  turbine_layer.applyEdits({
                    updateFeatures: turbine_feats
                  }).then((editResult) => {
                    resolve2(editResult);
                    console.groupEnd();
                  }).catch((error) => {
                    console.log("error =", error);
                    reject2(error);
                  });
                }
              });
              promises.push(prom);
            });
            Promise.all(promises).then((values) => {
              resolve('complete');
            });
            
          }).catch(function (error) {
            console.log("error from queryRelatedFeatures", error);
            reject(error);
          });
        });
      });
    });
    return promise1;
  };
  
  updateLayers = (envelope_layer: FeatureLayer, turbine_layer: FeatureLayer, project_name: string, layout_name: string) => {
    // set the Base Case first on the Envelope layer then query related features to update 
    // Base Case attribute on the turbine points for each layout
    const non_matching_query = `name_project = '${project_name}' AND id_layout <> '${layout_name}'`;
    const matching_query = `name_project = '${project_name}' AND id_layout = '${layout_name}'`;
    const non_matching_queryParams = envelope_layer.createQuery();
    const matching_queryParams = envelope_layer.createQuery();
    // query features from the project that do match layout name as set as true
    non_matching_queryParams.where = non_matching_query
    non_matching_queryParams.returnGeometry = false;
    this.performUpdate(envelope_layer, turbine_layer, non_matching_queryParams, 0).then((result) => {
      matching_queryParams.where = matching_query;
      matching_queryParams.returnGeometry = false;
      this.performUpdate(envelope_layer, turbine_layer, matching_queryParams, 1).then((result) => {
        // refresh the layer Views
        // turbine_layer.on("refresh", function(event) {
        //   console.log(event);
        // });
      
        turbine_layer.refresh();
        
        // envelope_layer.refresh();
        
      });
    });

    
    
  };

 

0 Kudos
rhughes522
Occasional Contributor
const layer_views = this.state.jimuMapView.view.allLayerViews;

layer_views.forEach((lyr_view) => { 
    const lyr = lyr_view.layer; 
    if (lyr.type === "feature") { 
        lyr.refresh(); 
    } 
});

 

This works to refresh the graphics.  We have to reference the Layer associated with the LayerView shown in the MapView.  Technically we can access the Feature Layer from the DataSources, but those layers are not aware of their LayerViews.  So to refresh the LayerView we must use the layer object directly associated with it.

0 Kudos