How to do filteration in AWS Amplify GraphQL Client
Asked Answered
T

2

12

I'm trying to implement GraphQL filter using Amplify GraphQL Client. I got a list of todos and wanted to retrieve list of todos that has status complete.

The Documentation only show how to get all items and single item

const allTodos = await API.graphql(graphqlOperation(queries.listTodos));
console.log(allTodos);

Could someone please point me how to apply filter to the listTodos so that it return todos with status complete only.

I tried to do the following but it is wrong.

API.graphql(graphqlOperation(queries.listTodos(filter: {
    status: {
        eq: "completed"
    }
})));
Tilney answered 27/12, 2018 at 15:43 Comment(3)
What does your schema and request mapping template look like? Does listTodos query take in a filter input or something? I know that AppSync generates these filter inputs for you if you choose to start with a sample schemaParoicous
yes, the code was auto generate by the amplify codegen. so it take filter, limit and next tokenTilney
Keep in mind that the filter is applied in the front-end (at least at the time being). You'll have to set a higher limit of todos to filter them correctlyMolly
W
23

I think I have an answer to your question, but I also have a similar question regarding the AWS Amplify codegen queries, mutations, etc. If you look at the code that was generated inside of ~/graphql folder, you'll find a declaration file similar to this:

export const listOrganizations = `query ListOrganizations(
  $filter: ModelOrganizationFilterInput
  $limit: Int
  $nextToken: String
) {
  listOrganizations(filter: $filter, limit: $limit, nextToken: $nextToken) {
    items {
      id
      name
      address
    }
    nextToken
  }
}
`;

You can see here that the first parameter to the ListOrganizations query (in your case, ListTodos query) takes a first argument of filter: $filter. I have figured out so far that you can modify this query by doing the following...

API.graphql(graphqlOperation(queries.listTodos, {
    filter: {
        status: {
            eq: "completed"
        }
    }
})));

This should filter out all Todos except the ones where their status is equal to completed. The problem that I am having is that I want to enable different levels of access control such that anyone with a Cognito User Pool Group of Admin may view @model as well as the @owner. And I was able to get this all working using the @auth transformer, but now my problem is that on some screens, I only want to display certain entities that are the owner of that entity and because I am also an Admin, the API defaults to getting me everything. I want to use this @filter or ModelOrganizationFilterInput to only give me the data where I am the owner. The only way I have found to do this was to add the owner field to my Schema, but then the API always provides the owner field and I want to filter that field out.

The only documentation that I can find on how the aws-amplify API and graphqlOperation methods is here: https://aws-amplify.github.io/docs/js/api but there are not many examples and they don't show much of how the API works on the client. I'm stuck.

Weismannism answered 31/12, 2018 at 6:13 Comment(5)
Hi @SuperVeetz, did you managed to solve your issue? As for the filter you suggested it work well for field with string type but how about for field with JSON object type.Tilney
Hi @MohammadHarith , To be honest, i'm not entirely sure, I would assume that if your object time was nested, then you may be able to do something like filter: { myObj { someProp { eq: "somevalue" } } } , this may work, may not. I have run into a bigger problem, which is how to enforce group based security, and now, how to filter by group based security.. ie. @auth transform declares dynamic or static security groups, can I filter results by a group name or by if a given username is contained inside a user group.Weismannism
yeah, its not working, the field has AWSJSON type and it return as one long string, so I just added a new field to specify the item from the object and use the filtration suggested earlier which work well in my case. Thanks!!Tilney
Hi @SuperVeetz, I'm stuck again, this time I need to filter todos with status of completed and pending. How can I achieve that? I tried status: { eq: ["completed","pending"] }, but not working.Tilney
Hi Mohammed, I'll be honest, I haven't run into this problem yet myself, but I believe that you can do use AND { eq: "completed" .. }, { eq: "pending" } .. I believe there is syntax to do this, but I am not 100% sure yet what it is.. Check the graphql amplify documenationWeismannism
M
1
  1. In your terminal, run amplify console and open the link it returns
  2. Scroll down and click on the API tab. AWS AppSync will open up.
  3. On the AWS AppSync menu, select Queries
  4. Create and test your queries. There is a filtering option depending on your schema.
  5. When you have your query working, copy it and paste it into your js code using backticks `` Here is an example:
const friendNames = await API.graphql(graphqlOperation(`query MyQuery {
        listFriends(filter: {userId: {eq: "randomID123456"}}) {
          items {
            firstname
            othername
          }
        }
      }`));

I can't seem to get stackoverflow to show the backticks `` in the code section above. You need to open backtick before the word query and put a closing backtick after the last curly bracket.
Edit - Edited answer with backticks

Machzor answered 17/6, 2023 at 16:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.