## Query item

Now that you were able to make a mutation, take the `id` from the created `Todo` instance and use it to retrieve data.

```dart
Future<Todo?> queryItem(Todo queriedTodo) async {
   try {
      final request = ModelQueries.get(Todo.classType, queriedTodo.id);
      final response = await Amplify.API.query(request: request).response;
      final todo = response.data;
      if (todo == null) {
        print('errors: ${response.errors}');
      }
      return todo;
   } on ApiException catch (e) {
      print('Query failed: $e');
      return null;
   }
}
```

## List items

You can get the list of items in `Amplify.API.query`:

```dart
Future<List<Todo?>> queryListItems() async {
  try {
    final request = ModelQueries.list(Todo.classType);
    final response = await Amplify.API.query(request: request).response;

    final todos = response.data?.items;
    if (todos == null) {
      print('errors: ${response.errors}');
      return <Todo?>[];
    }
    return todos;
  } on ApiException catch (e) {
    print('Query failed: $e');
  }
  return <Todo?>[];
}
```

### List subsequent pages of items

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.

```dart
const limit = 100;

Future<List<Todo?>> queryPaginatedListItems() async {
  final firstRequest = ModelQueries.list<Todo>(Todo.classType, limit: limit);
  final firstResult = await Amplify.API.query(request: firstRequest).response;
  final firstPageData = firstResult.data;

  // Indicates there are > 100 todos and you can get the request for the next set.
  if (firstPageData?.hasNextResult ?? false) {
    final secondRequest = firstPageData!.requestForNextResult;
    final secondResult = await Amplify.API.query(request: secondRequest!).response;
    return secondResult.data?.items ?? <Todo?>[];
  } else {
    return firstPageData?.items ?? <Todo?>[];
  }
}
```

## Query Predicates

Models also support the use of query predicates for comparison. These are accessible from the Model's attributes, for example `Blog["attribute"]["operator"]`. 

Supported operators: 
- `eq` - equal
- `ne` - not equal 
- `gt` - greater than 
- `ge` - greater than or equal 
- `lt` - less than 
- `le` - less than or equal
- `between` - Matches models where the given field begins with the provided value.
- `beginsWith` - Matches models where the given field is between the provided start and end values.
- `contains` - Matches models where the given field contains the provided value.

### Basic Equality Operator

Query for equality on a model's attribute.

```dart
const blogTitle = 'Test Blog 1';
final queryPredicate = Blog.NAME.eq(blogTitle);

final request = ModelQueries.list<Blog>(Blog.classType, where: queryPredicate);
final response = await Amplify.API.query(request: request).response;
final blogFromResponse = response.data?.items.first;
```

### Fetch by Parent ID

Get all Posts by parent ID

```dart
final blogId = blog.id;

final request =
    ModelQueries.list(Post.classType, where: Post.BLOG.eq(blogId));
final response = await Amplify.API.query(request: request).response;
final data = response.data?.items ?? <Post?>[];
```

### Less than

Return Posts with a rating less than 5.

```dart
const rating = 5;
    
final request = ModelQueries.list(Post.classType, where: Post.RATING.lt(rating));
final response = await Amplify.API.query(request: request).response;

final data = response.data?.items ?? <Post?>[];
```