aws graphql @connection not returning an array as expected?

373 views Asked by At

I have a graphql model as follows (a user can have many posts 1:m)

type User @model {
  id: ID!
  fullName: String!
  emailAddress: String!
  posts: [Post] @connection(name: "UserPostConnection")
}

type Post @model {
  id: ID!
  text: String!
  user: User @connection(name: "UserPostConnection")
  createdAt: String
  updatedAt: String
}

I am trying to return all the posts for a specific user, as so:

let queryInput = GetUserQuery(id: "879db4f2-1dad-47b9-b70d-8bca15bf2549")

appSyncClient?.fetch(query: queryInput, cachePolicy: .fetchIgnoringCacheData) { (result, error) in
            print(result?.data?.getUser?.posts)
        }
}        

However the result isn't returning an array, it is returning an optional:

Optional(AWSStackSocial.GetUserQuery.Data.GetUser.Post(snapshot: ["__typename": Optional("ModelPostConnection"), "nextToken": nil]))

I have confirmed that a) the user exists, and b) the posts also exists.

On AWS:

query {
    getUser(id: "879db4f2-1dad-47b9-b70d-8bca15bf2549") {
      id 
    posts {
      items {
        id
      }
    }
    }
}

Output:

{
  "data": {
    "getUser": {
      "id": "879db4f2-1dad-47b9-b70d-8bca15bf2549",
      "posts": {
        "items": [
          {
            "id": "04c4b571-6e92-4745-9a40-1a67a9d49d77"
          },
          {
            "id": "0f44fe6e-4e15-4a8c-b591-555e8fa1f60e"
          },
          {
            "id": "60c18c40-fea3-4ff3-8b21-df6857703dd2"
          }
        ]
      }
    }
  }
}
2

There are 2 answers

0
mickeysox On BEST ANSWER

I found the answer. The default depth level for amplify GraphQL is 2, so this needed to be changed to 3. This can be done by changing the maximum depth:

amplify codegen configure
1
Procrastin8 On

Anything in your model that doesn't have the required suffix (!) is by definition, optional, regardless of whether it exists or not. You have to guard against it being nil because it's defined such that it can be nil. If you own the model, you could change those to be required (I do not suggest this!). Otherwise, you will simply have to unwrap things when you process them.

guard let user = result?.data?.getUser, let posts = user.posts else { throw NoPostsError }