# Queries

## Query Basics

A query is a declarative dependency on an asynchronous source of data that is tied to a **unique key**. A query can be used with any Promise based method (including GET and POST methods) to fetch data from a server. If your method modifies data on the server, we recommend using [Mutations](./mutations.md) instead.



To subscribe to a query in your components , call `createQuery` with at least:



- A **unique key for the query**
- A function that returns a promise that:
  - Resolves the data, or
  - Throws an error



```svelte
<script lang="ts">
  import { createQuery } from '@tanstack/svelte-query'
  const todosQuery = createQuery(() => ({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  }))
</script>
```



The **unique key** you provide is used internally for refetching, caching, and sharing your queries throughout your application.

The query result returned by `createQuery` contains all of the information about the query that you'll need for templating and any other usage of the data:



```ts
const todosQuery = createQuery(() => ({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
}))
```



The `result` object contains a few very important states you'll need to be aware of to be productive. A query can only be in one of the following states at any given moment:

- `isPending` or `status === 'pending'` - The query has no data yet
- `isError` or `status === 'error'` - The query encountered an error
- `isSuccess` or `status === 'success'` - The query was successful and data is available

Beyond those primary states, more information is available depending on the state of the query:

- `error` - If the query is in an `isError` state, the error is available via the `error` property.
- `data` - If the query is in an `isSuccess` state, the data is available via the `data` property.
- `isFetching` - In any state, if the query is fetching at any time (including background refetching) `isFetching` will be `true`.

For **most** queries, it's usually sufficient to check for the `isPending` state, then the `isError` state, then finally, assume that the data is available and render the successful state:



```svelte
<script lang="ts">
  import { createQuery } from '@tanstack/svelte-query'

  const todosQuery = createQuery(() => ({
    queryKey: ['todos'],
    queryFn: () => fetchTodos(),
  }))
</script>

<div>
  {#if todosQuery.isPending}
    <p>Loading...</p>
  {:else if todosQuery.isError}
    <p>Error: {todosQuery.error.message}</p>
  {:else if todosQuery.isSuccess}
    {#each todosQuery.data as todo}
      <p>{todo.title}</p>
    {/each}
  {/if}
</div>
```



If booleans aren't your thing, you can always use the `status` state as well:



```svelte
<script lang="ts">
  const todosQuery = createQuery(() => ({
    queryKey: ['todos'],
    queryFn: () => fetchTodos(),
  }))
</script>

<div>
  {#if todosQuery.status === 'pending'}
    <p>Loading...</p>
  {:else if todosQuery.status === 'error'}
    <p>Error: {todosQuery.error.message}</p>
  {:else if todosQuery.status === 'success'}
    {#each todosQuery.data as todo}
      <p>{todo.title}</p>
    {/each}
  {/if}
</div>
```



TypeScript will also narrow the type of `data` correctly if you've checked for `pending` and `error` before accessing it.

### FetchStatus

In addition to the `status` field, you will also get an additional `fetchStatus` property with the following options:

- `fetchStatus === 'fetching'` - The query is currently fetching.
- `fetchStatus === 'paused'` - The query wanted to fetch, but it is paused. Read more about this in the [Network Mode](./network-mode.md) guide.
- `fetchStatus === 'idle'` - The query is not doing anything at the moment.

### Why two different states?

Background refetches and stale-while-revalidate logic make all combinations for `status` and `fetchStatus` possible. For example:

- a query in `success` status will usually be in `idle` fetchStatus, but it could also be in `fetching` if a background refetch is happening.
- a query that mounts and has no data will usually be in `pending` status and `fetching` fetchStatus, but it could also be `paused` if there is no network connection.

So keep in mind that a query can be in `pending` state without actually fetching data. As a rule of thumb:

- The `status` gives information about the `data`: Do we have any or not?
- The `fetchStatus` gives information about the `queryFn`: Is it running or not?



