## Query by Id
Now that you were able to make a mutation, take the `Id` that was printed out and use it in your query to retrieve data.
```swift
func getTodo() async {
do {
let result = try await Amplify.API.query(
request: .get(Todo.self, byId: "9FCF5DD5-1D65-4A82-BE76-42CB438607A0")
)
switch result {
case .success(let todo):
guard let todo = todo else {
print("Could not find todo")
return
}
print("Successfully retrieved todo: \(todo)")
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
} catch let error as APIError {
print("Failed to query todo: ", error)
} catch {
print("Unexpected error: \(error)")
}
}
```
```swift
func getTodo() -> AnyCancellable {
let sink = Amplify.Publisher.create {
try await Amplify.API.query(
request: .get(Todo.self, byId: "9FCF5DD5-1D65-4A82-BE76-42CB438607A0")
)
}
.sink {
if case let .failure(error) = $0 {
print("Got failed event with error \(error)")
}
}
receiveValue: { result in
switch result {
case .success(let todo):
guard let todo = todo else {
print("Could not find todo")
return
}
print("Successfully retrieved todo: \(todo)")
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
}
return sink
}
```
## List Query
You can get the list of items using `.list` with optional parameters `limit` and `where` to specify the page size and condition. By default, the page size is 1000.
```swift
func listTodos() async {
let todo = Todo.keys
let predicate = todo.name == "my first todo" && todo.description == "todo description"
let request = GraphQLRequest.list(Todo.self, where: predicate, limit: 1000)
do {
let result = try await Amplify.API.query(request: request)
switch result {
case .success(let todos):
print("Successfully retrieved list of todos: \(todos)")
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
} catch let error as APIError {
print("Failed to query list of todos: ", error)
} catch {
print("Unexpected error: \(error)")
}
}
```
```swift
func listTodos() -> AnyCancellable {
let todo = Todo.keys
let predicate = todo.name == "my first todo" && todo.description == "todo description"
let request = GraphQLRequest.list(Todo.self, where: predicate, limit: 1000)
let sink = Amplify.Publisher.create {
try await Amplify.API.query(request: request)
}
.sink {
if case let .failure(error) = $0 {
print("Got failed event with error \(error)")
}
}
receiveValue: { result in
switch result {
case .success(let todos):
print("Successfully retrieved list of todos: \(todos)")
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
}
return sink
}
```
### List subsequent pages of items
If you are using SwiftUI and have SwiftUI imported in the same code file, you will need to import the class `Amplify.List` to resolve name collision with `SwiftUI.List`:
```swift
import SwiftUI
import Amplify
import class Amplify.List
```
For large data sets, you'll need to paginate through the results. After receiving the first page of results, you can check if there is a subsequent page and obtain the next page.
```swift
var todos: [Todo] = []
var currentPage: List?
func listFirstPage() async {
let todo = Todo.keys
let predicate = todo.name == "my first todo" && todo.description == "todo description"
let request = GraphQLRequest.list(Todo.self, where: predicate, limit: 1000)
do {
let result = try await Amplify.API.query(request: request)
switch result {
case .success(let todos):
print("Successfully retrieved list of todos: \(todos)")
self.currentPage = todos
self.todos.append(contentsOf: todos)
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
} catch let error as APIError {
print("Failed to query list of todos: ", error)
} catch {
print("Unexpected error: \(error)")
}
}
func listNextPage() async {
if let current = self.currentPage, current.hasNextPage() {
do {
let todos = try await current.getNextPage()
self.todos.append(contentsOf: todos)
self.currentPage = todos
} catch {
print("Failed to get next page \(error)")
}
}
}
```
## List all pages
If you want to get all pages, retrieve the subsequent page when you have successfully retrieved the first or next page.
1. Update the above method `listFirstPage()` to `listAllPages()`
2. Call `listNextPageRecursively()` in the success block of the query in `listAllPages()`
2. Update the `listNextPage()` to `listNextPageRecursively()`
3. Call `listNextPageRecursively()` in the success block of the query in `listNextPageRecursively()`
The completed changes should look like this:
```swift
var todos: [Todo] = []
var currentPage: List?
func listAllPages() async { // 1. Updated from `listFirstPage()`
let todo = Todo.keys
let predicate = todo.name == "my first todo" && todo.description == "todo description"
let request = GraphQLRequest.list(Todo.self, where: predicate, limit: 1000)
do {
let result = try await Amplify.API.query(request: request)
switch result {
case .success(let todos):
print("Successfully retrieved list of todos: \(todos)")
self.currentPage = todos
self.todos.append(contentsOf: todos)
await self.listNextPageRecursively() // 2. Added
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
} catch let error as APIError {
print("Failed to query list of todos: ", error)
} catch {
print("Unexpected error: \(error)")
}
}
func listNextPageRecursively() async { // 3. Updated from `listNextPage()`
if let current = currentPage, current.hasNextPage() {
do {
let todos = try await current.getNextPage()
self.todos.append(contentsOf: todos)
self.currentPage = todos
await self.listNextPageRecursively() // 4. Added
} catch {
print("Failed to get next page \(error)")
}
}
}
```