## 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)") } } } ```