Skip to main content
useLazyQuery is an auto-generated hook that provides a trigger function to fetch data on demand, rather than automatically on component mount.

Overview

For an endpoint named getPosts, the generated lazy hook will be useLazyGetPostsQuery.
export const postsApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (build) => ({
    getPosts: build.query<Post[], void>({
      query: () => '/posts',
    }),
  }),
});

export const { useLazyGetPostsQuery } = postsApi;

Signature

const [trigger, result, lastArg] = useLazyXxxQuery(options?);
options
UseQueryOptions
Optional configuration object or signal

Return Value

Returns an object with trigger function and query state:
trigger
(arg: QueryArg, options?) => Promise
Function to trigger the query. Returns a promise that resolves to the result.Options:
  • preferCacheValue: boolean - Use cached value if available (default: false)
data
Signal<ResultType | undefined>
The returned data from the query
isLoading
Signal<boolean>
true if the query is loading
isFetching
Signal<boolean>
true if the query is currently fetching
isSuccess
Signal<boolean>
true if the query has succeeded
isError
Signal<boolean>
true if the query has errored
error
Signal<Error | undefined>
The error object if the query failed
lastArg
Signal<QueryArg | undefined>
The last argument passed to the trigger function
reset
() => void
Function to reset the query state

Usage Examples

Basic Usage

import { useLazyGetPostsQuery } from './api';

@Component({
  selector: 'app-posts',
  template: `
    <button (click)="loadPosts()">Load Posts</button>
    
    @if (postsQuery.isLoading()) {
      <p>Loading...</p>
    }
    @if (postsQuery.data(); as posts) {
      @for (post of posts; track post.id) {
        <div>{{ post.title }}</div>
      }
    }
  `,
})
export class PostsComponent {
  postsQuery = useLazyGetPostsQuery();
  
  loadPosts() {
    this.postsQuery();
  }
}

With Arguments

export class PostSearchComponent {
  searchQuery = useLazySearchPostsQuery();
  
  search(term: string) {
    this.searchQuery(term).unwrap()
      .then(results => console.log('Search results:', results))
      .catch(error => console.error('Search failed:', error));
  }
}

With preferCacheValue

export class PostDetailsComponent implements OnInit {
  postId = input.required<number>();
  postQuery = useLazyGetPostQuery();
  
  ngOnInit() {
    // Use cache if available, otherwise fetch
    this.postQuery(this.postId(), { preferCacheValue: true });
  }
}

Reset State

export class PostSearchComponent {
  searchQuery = useLazySearchPostsQuery();
  
  search(term: string) {
    this.searchQuery(term);
  }
  
  clearSearch() {
    this.searchQuery.reset();
  }
}

Access Last Argument

@Component({
  template: `
    <p>Last search: {{ searchQuery.lastArg() }}</p>
    <p>Results: {{ searchQuery.data()?.length }}</p>
  `,
})
export class PostSearchComponent {
  searchQuery = useLazySearchPostsQuery();
  
  search(term: string) {
    this.searchQuery(term);
  }
}

When to Use

Use useLazyQuery

  • User-triggered actions (search, load more)
  • Conditional data loading
  • On-demand fetching based on user interaction
  • Pagination with manual page controls

Use useQuery

  • Data needed on component mount
  • Automatic refetching
  • Real-time data with polling
  • Router parameter-based fetching

Comparison with useQuery

// useQuery: Automatic fetching
const postsQuery = useGetPostsQuery();
// ✅ Fetches immediately on mount
// ✅ Refetches automatically with options
// ❌ Can't control when to fetch

// useLazyQuery: Manual triggering
const postsQuery = useLazyGetPostsQuery();
postsQuery(); // Trigger fetch manually
// ✅ Full control over when to fetch
// ✅ Can pass different arguments
// ❌ Requires manual trigger
For most use cases, prefer useQuery. Only use useLazyQuery when you need explicit control over when the query executes.

See Also

Build docs developers (and LLMs) love