useActiveMarkets
The useActiveMarkets hook is a wrapper over useActiveConditions that groups the conditions a game is offering into markets, with groupConditionsByMarket.
Usage
import { useActiveMarkets } from '@azuro-org/sdk'
const { data, isFetching, error } = useActiveMarkets(props)This hook needs a live feed connection. Like
useActiveConditions, it requires the
FeedSocketProvider and ConditionUpdatesProvider — both are already included in
AzuroSDKProvider, so there is nothing to do unless you compose the
providers by hand. If you do, and one of them is missing, the hook fails at runtime, not at compile
time.
Props
{
gameId: string
includeHidden?: boolean // keep `hidden` conditions and outcomes in the result; default false
extended?: boolean // opt-in: include new conditions/markets not present in the dictionaries package
chainId?: ChainId
query?: QueryParameter<UseConditionsQueryFnData> // useQuery params, without `select`
}query.select is not supported here. Grouping and the visibility filter both run after the query,
so a select would see the raw, unfiltered conditions and its result would then be treated as if it
were still a ConditionDetailedData[]. Every other useQuery option (refetchInterval, enabled,
placeholderData, …) is forwarded as usual.
If you need a select, call useConditions and group the
result yourself with
groupConditionsByMarket.
gameId property is not the same as id. Each game fetched using useGames hook contains the gameId:
import { useGames } from '@azuro-org/sdk'
const { data } = useGames()
const gameId = data?.games[0]?.gameIdextended is forwarded to the underlying useActiveConditions call. Set it to true to also surface new-generation markets (conditions whose conditionId[0] === '5') in the grouped result — groupConditionsByMarket already understands the new shape. See the useActiveConditions docs for the full caveat, especially if your app reads @azuro-org/dictionaries directly.
hidden conditions and outcomes are dropped by default.
Three rules, all of them skipped when includeHidden: true:
- a condition currently flagged
hiddenis dropped; - inside a condition that is kept, outcomes flagged
hiddenare dropped; - a condition left with no visible outcome is dropped too — and a market left with no condition therefore doesn’t appear at all.
The product rule to apply: while a game is running, hidden markets and outcomes are not being offered, so they stay out of the grid; once the game is over, they are part of what the bettor should see.
import { GameState } from '@azuro-org/toolkit'
const { data } = useActiveMarkets({
gameId,
includeHidden: gameState === GameState.Finished,
})Visibility is decided on the live value from the feed, after every condition of the game has been subscribed, and it is latched one way — a market that stops stays in the grid, locked, instead of disappearing under the bettor. See How visibility is decided.
Settlement is per-outcome. ConditionState is only ever Active or Stopped — a condition carries
no result. Within a single condition, outcomes settle independently: Won, Lost, Canceled (voided,
stake refunded) or still Active. Read MarketOutcome.state, or
isOutcomeSettled, for a result.
Return Value
The hook is no longer a plain UseQueryResult: markets are grouped after the query, so data is typed
separately from the query’s own data.
UseActiveMarketsResultimport { type UseQueryResult } from '@tanstack/react-query'
type UseActiveMarketsResult = {
data: GameMarkets | undefined
} & Omit<UseQueryResult<ConditionDetailedData[]>, 'data'>data is undefined until there is at least one visible condition to group. Everything else behaves as
it does on useQuery — isLoading, isFetching, isPlaceholderData, status, error and refetch
all come from the underlying query untouched.
type GameMarkets = Market[]
type Market = {
marketKey: string
name: string
description: string
conditions: MarketCondition[]
category: ConditionCategory
type?: 'legacy' | 'v5'
}
type MarketCondition = {
conditionId: string
state: ConditionState
category: ConditionCategory
sort: number
margin: string
hidden?: boolean
isExpressForbidden: boolean
outcomes: MarketOutcome[]
}
type MarketOutcome = {
selectionName: string
odds: number
gameId: string
isExpressForbidden: boolean
hidden: boolean
/** the per-outcome source of truth: Active | Stopped | Won | Lost | Canceled */
state: OutcomeState
} & Selection
type Selection = {
conditionId: string
outcomeId: string
}
enum ConditionState {
Active = 'Active',
Stopped = 'Stopped',
}
enum OutcomeState {
Active = 'Active',
Canceled = 'Canceled',
Stopped = 'Stopped',
Won = 'Won',
Lost = 'Lost'
}
type ConditionCategory =
| 'correct_score'
| 'handicap'
| 'handicap_3_way'
| 'odd_even'
| 'participant_and_total'
| 'participant_and_yes_no'
| 'participant_slash_participant'
| 'players'
| 'result'
| 'result_or_neither'
| 'total'
| 'total_3_way'
| 'winner'
| 'yes_no'
| string // extensible — new categories may appear; null when unset
| nullhidden on the returned conditions and outcomes is the value the fetch reported, not the live,
latched value the filter used. A row can be present with hidden: true on it — it was hidden when
fetched and has since been reported visible. Don’t re-filter on it.