Make layer refresh method return a promise

1234
4
04-13-2022 02:51 AM
Status: Closed
Labels (1)
JonasDePelsmaeker
New Contributor II

Up until the current API version (4.23), the refresh method on refreshable layers returns void.

I think it would be useful if the method got converted to a promise so developers can react when the refresh is successful or has failed.

For the moment, I have implemented something that notifies me when the refresh is done regardless of the fact that it has succeeded or failed.

new Promise<void>((resolve, reject) => {
    layer.refresh();
    view.whenLayerView(layer)
        .then((layerView) => whenFalseOnce(layerView, "updating", () => resolve()))
        .catch((reason) => reject(reason));
})

The main goal would be to react when a refresh on a layer has failed.

4 Comments
YannCabon

Hi Jonas,

Your function is the way to go. This is not possible to change RefreshableLayer.refresh() for a couple of reasons.

- Layers are not aware of the views and layerviews. Multiple MapViews can display a same map and layers. So that function can only be done from the application code that knows about both the view and the layer.

- There is no way to detect when a refresh is actually finished. While the layerview is refreshing, the user can still pan and zoom, and "updating" will remain true until the data is fully updated.

Here's another version of your function that ensure the layerview is updating then not updating:

 

async function refreshLayer(layer, view) {
  layer.refresh();
  const layerView = view.allLayerViews.find((layerView) => layerView.layer === layer);
  await reactiveUtils.once(() => layerView.updating);
  await reactiveUtils.once(() => !layerView.updating);
}

 


Your goal is to detect when a refresh has failed. It can mean a lot of things. In the case of a tile layer for example, we can't consider that the refresh has failed because one tile failed to refresh. For feature layers, data is fetched using different strategies depending on the server capabilities.

It would be helpful to get more information about the information you would need, and how it would translate in the UX. 

The only way to detect that some data failed to be fetched at the moment is to create a log interceptor https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#log to intercept the messages in the console. 

JonasDePelsmaeker

Hi Yann,

Thank you for your response and your explanation! It is indeed difficult to define when a refresh was actually failed.

The client wants to have a  general 'refresh map' button. When clicking on that button, all the layers of the map should be refreshed. After completing the refresh (either a failed or succeeded refresh), a snackbar is shown to the user with the message the refresh is successful or not.

I have implemented your proposed solution by using the log interceptor. This works perfectly for my client's purpose.

BjornSvensson
Status changed to: Closed
 
SaurabhUpadhyaya

Hi @BjornSvensson 

I read your explanation, also have similiar requirement but some diffrent way.

I am using JS API 4.28, in that i have total 7 layers(Feature Layers & Map Image Layers) using definitionexpression to filter the data and generate dynamic renderer for each layers and set the rendered to each layers.

Now the issue is, layers attribute values are changed on button click, and rendrer generated on the updated values sometimes renderer not generated correctly.. and colors are not displayed correctly.

When i reload the page it is shown correctly, but my requirement is to refresh the layers and display the updated layers on map.

I have tried layer.refresh() but it is not working correctly.

My intrest is to refresh the map/view only bcoz after reloading it is displaying correctly, so now my req is to suggest some workaround to reload/refresh the map/view of all added layers.