CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
13.04k stars 3.51k forks source link

Error on datasource remove #11332

Closed Jean-Dum closed 1 year ago

Jean-Dum commented 1 year ago

I a using Cesium 1.105.0 with React 18 on StrictMode. I am adding a datasource to viewer datasources, then removing it on component unmount. When removing it I have this error:

An error occurred while rendering. Rendering has stopped. TypeError: Cannot read property 'length' of undefined TypeError: Cannot read property 'length' of undefined at DataSourceDisplay.update (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:153412:27) at Viewer._onTick (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:250246:45) at Event.raiseEvent (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:23095:20) at Clock.tick (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:130830:15) at CesiumWidget.render (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:214044:37) at render2 (http://localhost:6006/node_modules/.vite-storybook/deps/cesium.js?v=1c1f44d1:213460:18)

Here is my code:

/**
 * Context allowing to use a cesium datasource
 */
function DataSourceProvider({ children, collectionName }: { children: ReactNode; collectionName: string; }) {
  const { viewer } = useCesiumViewer();
  const dataSource = useRef<CustomDataSource>(new CustomDataSource(collectionName));

  // Initialize collection
  useEffect(() => {
    if (!viewer.dataSources.contains(dataSource.current)) {
      viewer.dataSources.add(dataSource.current);
    }

    // Delete collection on component unmount
    return () => {
      if (!viewer.dataSources.isDestroyed() && viewer.dataSources.contains(dataSource.current)) {
        viewer.dataSources.remove(dataSource.current, true);
        viewer.scene.requestRender();
      }
    };
  }, [viewer]);

  return <DataSourceContext.Provider value={dataSource.current}>{children}</DataSourceContext.Provider>;
}

I could use datasource.current.entities.removeAll() but the viewer datasources list would keep useless datasources after emptying them. Even returning null instead of DataSourceContext object, the error still produces on component unmount.

So this error comes from the viewer.datasources.remove function, would you know if it is a bug or if I made a mistake, and if so how to prevent this from happening?

Thank you for your help!

ggetz commented 1 year ago

Hi @Jean-Dum,

I think this depends on the implementation of the CustomDataSource type referenced here. DataSourceCollection.remove typically removes the associated entities.

CesiumJS is a big project, so we use GitHub for feature requests and bug tracking exclusively. In the future, please take any questions to the Cesium Forum where there are members of the community and developers from the team who can help. Thanks!