Closed kiranshetty07061999 closed 3 years ago
As far as I'm aware the Viewer
does initialize the Presentation
library. It's kind of hard to understand what's happening in your app, but my guess is that SelectionOfComponentsData
gets called before the initialization is complete. I think the callback that tells you it's complete is onIModelConnected
- please try calling your function from there.
Adding @aruniverse and @kckst8 into the conversation in case they have better suggestions.
I tried calling it from onIModelConnected but that did not work.....I am getting this error
Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
Hello, can you provide your onimodelconnected callback snippet?
const onIModelConnected = (_imodel: IModelConnection) => { IModelApp.viewManager.onViewOpen.addOnce(async (vp: ScreenViewport) => { const viewStyle: DisplayStyleSettingsProps = { viewflags: { visEdges: false, shadows: true } }
i have called this in the Viewer
onIModelConnected = {onIModelConnected}
Have you tried adding your presentation listener in that function (Presentation. Presentation.selection.selectionChange.addListener(_onSelectionChanged)?
I missed the part that SelectionOfComponentsData
uses a hook. Try removing the hook and simply changing it to this:
export function SelectionOfComponentsData() {
Presentation.selection.selectionChange.addListener(_onSelectionChanged);
const _onSelectionChanged = async (evt: SelectionChangeEventArgs, selectionProvider: ISelectionProvider) => {
const selection = selectionProvider.getSelection(evt.imodel, evt.level);
console.log(selection);
}
}
I tried adding this code
import { RequestPriority } from "@bentley/presentation-common"; import { Presentation, PresentationManagerMode } from "@bentley/presentation-backend"; import rpcs from "../common/Rpcs"; // initialize presentation-backend Presentation.initialize({ rulesetDirectories: [path.join("assets", "presentation_rules")], localeDirectories: [path.join("assets", "locales")], mode: PresentationManagerMode.ReadWrite, taskAllocationsMap: {
}, useMmap: true, updatesPollInterval: 20, });
but i am not sure how to include rpcs file
@grigasp It worked...thanks a lot
Hi there,
I am trying to get the EcInstanceId of the components of the model upon click. I tried implementing the same by using the following set of codes
export function SelectionOfComponentsData() {
React.useEffect(() => {
);
const _onSelectionChanged = async (evt: SelectionChangeEventArgs, selectionProvider: ISelectionProvider) => { const selection = selectionProvider.getSelection(evt.imodel, evt.level); console.log(selection) };
I have written this set of codes in a different file and have imported it in my App.tsx.... But when i run my code , I get the following error
How do i resolve this? I have pasted my App.tsx and SelectionOfComponents here
App.tsx
/*---------------------------------------------------------------------------------------------
import "./App.scss";
import { BrowserAuthorizationClientConfiguration } from "@bentley/frontend-authorization-client"; import { DisplayStyleSettingsProps } from "@bentley/imodeljs-common"; import { FitViewTool, IModelApp, IModelConnection, ScreenViewport, StandardViewId,IModelAppOptions } from "@bentley/imodeljs-frontend"; import { Viewer } from "@itwin/web-viewer-react"; import React, { useEffect, useState } from "react"; import { Header } from "./Header"; import { history } from "./history"; import {ISelectionProvider, Presentation, SelectionChangeEventArgs , PresentationManagerProps } from "@bentley/presentation-frontend"; import { ChangedValueState, IModel } from "@bentley/imodeljs-common"; import { SelectionOfComponentsData } from "./components/components/SelectionOfComponents";
const App: React.FC = () => { const [isAuthorized, setIsAuthorized] = useState( (IModelApp.authorizationClient?.hasSignedIn && IModelApp.authorizationClient?.isAuthorized) || false ); const [isLoggingIn, setIsLoggingIn] = useState(false); const [iModelId, setIModelId] = useState(process.env.IMJS_IMODEL_ID); const [contextId, setContextId] = useState(process.env.IMJS_CONTEXT_ID);
if (!process.env.IMJS_AUTH_CLIENT_CLIENT_ID) { throw new Error( "Please add a valid OIDC client id to the .env file and restart the application. See the README for more information." ); } if (!process.env.IMJS_AUTH_CLIENT_SCOPES) { throw new Error( "Please add valid scopes for your OIDC client to the .env file and restart the application. See the README for more information." ); } if (!process.env.IMJS_AUTH_CLIENT_REDIRECT_URI) { throw new Error( "Please add a valid redirect URI to the .env file and restart the application. See the README for more information." ); }
const authConfig: BrowserAuthorizationClientConfiguration = { scope: process.env.IMJS_AUTH_CLIENT_SCOPES ?? "", clientId: process.env.IMJS_AUTH_CLIENT_CLIENT_ID ?? "", redirectUri: process.env.IMJS_AUTH_CLIENT_REDIRECT_URI ?? "", postSignoutRedirectUri: process.env.IMJS_AUTH_CLIENT_LOGOUT_URI, responseType: "code", authority: "https://ims.bentley.com", };
useEffect(() => { if (isAuthorized) { const urlParams = new URLSearchParams(window.location.search); if (urlParams.has("contextId")) { setContextId(urlParams.get("contextId") as string); } else { if (!process.env.IMJS_CONTEXT_ID) { throw new Error( "Please add a valid context ID in the .env file and restart the application or add it to the contextId query parameter in the url and refresh the page. See the README for more information." ); } }
}, [isAuthorized]);
useEffect(() => { if (contextId && iModelId && isAuthorized) { history.push(
?contextId=${contextId}&iModelId=${iModelId}
); } }, [contextId, iModelId, isAuthorized]);useEffect(() => { if (isLoggingIn && isAuthorized) { setIsLoggingIn(false); } }, [isAuthorized, isLoggingIn]);
const onLoginClick = async () => { setIsLoggingIn(true); await IModelApp.authorizationClient?.signIn(); };
const onLogoutClick = async () => { setIsLoggingIn(false); await IModelApp.authorizationClient?.signOut(); setIsAuthorized(false); };
const onIModelConnected = (_imodel: IModelConnection) => { IModelApp.viewManager.onViewOpen.addOnce(async (vp: ScreenViewport) => { const viewStyle: DisplayStyleSettingsProps = { viewflags: { visEdges: false, shadows: true } }
} const onIModelAppInit = () => { setIsAuthorized(IModelApp.authorizationClient?.isAuthorized || false); IModelApp.authorizationClient?.onUserStateChanged.addListener(() => { setIsAuthorized( (IModelApp.authorizationClient?.hasSignedIn && IModelApp.authorizationClient?.isAuthorized) || false ); }); };
/** NOTE: This function will execute the "Fit View" tool after the iModel is loaded into the Viewer.
to honor default views when they are present instead (the Viewer will still apply a similar function to iModels that do not have a default view). */ const viewConfiguration = (viewPort: ScreenViewport) => { const tileTreesLoaded = () => { return new Promise((resolve, reject) => { const start = new Date(); const intvl = setInterval(() => { if (viewPort.areAllTileTreesLoaded) { clearInterval(intvl); resolve(true); } const now = new Date(); // after 20 seconds, stop waiting and fit the view if (now.getTime() - start.getTime() > 20000) { reject(); } }, 100); }); };
tileTreesLoaded().finally(() => { IModelApp.tools.run(FitViewTool.toolId, viewPort, true, false); viewPort.view.setStandardRotation(StandardViewId.Iso); }); };
// This is to record the on-click events
SelectionOfComponentsData()
return (
); };
export default App;
SelectionOfComponents.tsx
import { IModelApp,IModelConnection } from "@bentley/imodeljs-frontend"; import { ISelectionProvider, Presentation, PresentationManager, SelectionChangeEventArgs,PresentationManagerProps } from "@bentley/presentation-frontend"; import React, { useEffect } from "react"; import { SelectionSet } from "@bentley/imodeljs-frontend"; import {PresentationUnitSystem} from "@bentley/presentation-common" import { TileAdmin } from "@bentley/imodeljs-frontend";
export function SelectionOfComponentsData() {
React.useEffect(() => {
);
const _onSelectionChanged = async (evt: SelectionChangeEventArgs, selectionProvider: ISelectionProvider) => { const selection = selectionProvider.getSelection(evt.imodel, evt.level); console.log(selection)
};
// const getModelData = async (imodel:IModelConnection)=>{ // const query =
// select UserLabel,ECInstanceId from Biscore.Geometricelement3d //
// const results = imodel.query(query)// const values = [];
// for await (const row of results){ // values.push(row); // // console.log(row); // }
// return values;
// }
}