diff --git a/frontend/web/components/EnvironmentReadyChecker.tsx b/frontend/web/components/EnvironmentReadyChecker.tsx index 6f065fe66be1..cf64389cbbef 100644 --- a/frontend/web/components/EnvironmentReadyChecker.tsx +++ b/frontend/web/components/EnvironmentReadyChecker.tsx @@ -1,4 +1,4 @@ -import { PropsWithChildren } from 'react' +import { PropsWithChildren, useEffect, useState } from 'react' import { useGetEnvironmentQuery } from 'common/services/useEnvironment' import { useRouteMatch } from 'react-router-dom' @@ -48,10 +48,20 @@ const EnvironmentReadyChecker = ({ // 'create' is the new-env form route sentinel, not an env ID. const hasEnvironmentId = !!environmentId && environmentId !== 'create' + // Gate pollingInterval on a state flag rather than reading `data` inside the + // hook options: `data` is the same hook's destructured result and is + // unassigned at options-evaluation time, so a direct reference silently + // evaluates to `undefined` and polling never starts. + const [pollingStopped, setPollingStopped] = useState(false) + + useEffect(() => { + setPollingStopped(false) + }, [environmentId]) + const { data, isError } = useGetEnvironmentQuery( { id: environmentId || '' }, { - pollingInterval: data?.is_creating ? POLL_INTERVAL_MS : 0, + pollingInterval: pollingStopped ? 0 : POLL_INTERVAL_MS, skip: !hasEnvironmentId, }, ) @@ -61,6 +71,12 @@ const EnvironmentReadyChecker = ({ !!data && !!projectId && data.project !== Number(projectId) const environmentNotFound = hasEnvironmentId && (wrongProject || isError) + useEffect(() => { + if ((data && !data.is_creating) || isError || wrongProject) { + setPollingStopped(true) + } + }, [data, isError, wrongProject]) + if (!hasEnvironmentId) return children if (environmentNotFound) return if (!data) return