injectConvex
injectConvex() returns the ConvexClient instance that provideConvex() registered. Use it for
the cases the reactive helpers do not cover: one-shot queries, imperative mutations and actions from
non-component code, and manual subscriptions you want to own yourself.
Signature
Section titled “Signature”function injectConvex(options?: InjectConvexOptions): ConvexClient;
interface InjectConvexOptions { /** * Environment injector used to resolve the Convex client when creating * helpers outside the current injection context. */ injectRef?: EnvironmentInjector;}| Parameter | Type | Purpose |
|---|---|---|
options.injectRef |
EnvironmentInjector |
Resolve the client from an explicit injector when calling outside an injection context. |
The return value is the ConvexClient from convex/browser — the same instance every helper in this
library uses, not a wrapper. Its full API is available: query, mutation, action, onUpdate,
connectionState, and the underlying client (a BaseConvexClient).
import { Injectable } from '@angular/core';import { injectConvex } from 'convex-angular';
import { api } from './convex/api';
@Injectable({ providedIn: 'root' })export class TodoAdminService { // The very same ConvexClient instance provideConvex(...) registered under // the CONVEX token. Throws if provideConvex(...) was never called. private readonly convex = injectConvex();
/** One-shot query outside of any subscription. */ async count(): Promise<number> { const todos = await this.convex.query(api.todos.list, { count: 100 }); return todos.length; }
/** Imperative mutation, for code that is not a component interaction. */ async create(title: string): Promise<void> { await this.convex.mutation(api.todos.create, { title }); }
/** Imperative action. */ async completeAll(): Promise<number> { return this.convex.action(api.todos.completeAll, {}); }
/** Manual subscription; you own the unsubscribe. */ watch(onTodos: (titles: string[]) => void): () => void { return this.convex.onUpdate(api.todos.list, { count: 100 }, (todos) => { onTodos(todos.map((todo) => todo.title)); }); }}Lifetime
Section titled “Lifetime”The client is created by provideConvex() and closed automatically when the owning injector is
destroyed. Do not call close() on it yourself — the rest of the application shares the instance.
Errors
Section titled “Errors”injectConvex() throws a focused setup error when provideConvex() was never called, instead of
Angular’s generic NullInjectorError:
Could not find `CONVEX`. Make sure to call `provideConvex(...)` once in your root application providers (for example, in `app.config.ts`).Calling it outside an injection context without an injectRef throws:
injectConvex() must be called from an injection context (for example, a component or service field initializer or constructor), or be given an explicit injector via the `injectRef` option to create it later from plain code.Server-side rendering
Section titled “Server-side rendering”During a server render the client is constructed with disabled: true. Direct calls to
convex.query(), convex.mutation(), and convex.action() throw:
ConvexClient is disabledconvex.onUpdate() registration is a no-op there, and the convex.client getter throws. Check
convex.disabled before using the client imperatively in code that can run on the server. See
Server-side rendering.
The CONVEX token
Section titled “The CONVEX token”const CONVEX: InjectionToken<ConvexClient>;The injection token provideConvex() registers the client under. injectConvex() reads it, and you
can inject it directly when you want plain Angular DI semantics:
import { inject } from '@angular/core';import { CONVEX } from 'convex-angular';
export class TodoService { private readonly convex = inject(CONVEX);}The difference is only in the failure mode: inject(CONVEX) produces Angular’s standard
NullInjectorError when the provider is missing, while injectConvex() produces the focused message
above. The token is also the seam to override in tests — provideConvexTesting() registers a
MockConvexClient under it.
Related
Section titled “Related”- Connection state — observe the client’s WebSocket connectivity.
- Server-side rendering — what the client does during a server render.