How to access variables on a custom resolver?

So I have in my schema:

type Login {
  user: User!
  secret: String!
}

input LoginInput {
  email: String!
  password: String!
}

type Mutation {
  logout: Logout! @resolver(name: "Logout")
  login(data: LoginInput!): Login! @resolver(name: "Login")
}

Then my Login function:

Update(Function("Login"), {
  role: "admin",
  body: Query(
    Lambda(
      "data",
      Let(
        {
          auth: Login(
            Match(
              Index("unique_User_email"),
              Select(["email"], Var("data"))
            ),
            {
              password: Select(["password"], Var("data"))
            }
          )
        },
        {
          user: Get(
            Select(['instance'], Var('auth'))
          ),
          secret: Select(['secret'], Var('auth'))
        }
      )
    )
  )
});

I run:

mutation {
  login (
    data: {
      email: "test2@email.com",
      password: "password"
    }
  ) {
    user {
      name
      email
    }
    secret
  }
}

I keep getting:

 [
  {
    "message": "Value not found at path [email].",
    "extensions": {
      "code": "value not found"
    }
  }
]

So I can’t access the data.email from the data arguments on the Lambda function. I could have figured this out on my own if I can do some kind of inspection or console.log

I needed to do ["data"] on the arguments of the lambda function, also can’t do this approach because it seems I can’t assign the result of Login to a variable in Let, because both user and secret becomes null for some reason, I can only do:

Update(Function("Login"), {
  role: "admin",
  body: Query(
    Lambda(
      ["data"],
      Select(
        ["secret"],
        Login(
           Match(
             Index("unique_User_email"),
             Select(["email"], Var("data"))
           ),
           {
             password: Select(["password"], Var("data"))
           }
         )
      )
    )
  )
});

Yea, all UDFs for GraphQL custom resolvers must put the lambda arguments in an array, even if there is only one argument. Or use an empty array if there are no arguments.

You can stash the result of Login in a variable and use it later. I’m not sure what happened in your case.

image

Yes you can, I tried invoking the udf on the shell and it worked, but when using graphql it doesn’t work. I used this here GitHub - aprilmintacpineda/react-native-faunadb: A React-Native sample application that uses FaunaDB serverless architecture. maybe you can replicate? You don’t need to boot the entire app, just the graphql playground on the dashboard will do.

Oh!

The difference is that the Login function returns an entire Document. And entire Token document. By returning an object directly from the GraphQL resolver the API doesn’t know what to do with it.

If you want Login type to only be used as a return type from the mutation, use @embedded with it. Otherwise, the API expects these to be actual Documents, and will create a Collection for them, etc.

type Login @embedded {
  user: User!
  secret: String!
}
1 Like

AHA! I will try to change this to that.

Now it’s a different error:

Update(Function("Login"), {
  role: "admin",
  body: Query(
    Lambda(
      ["email", "password"],
      Let(
        {
          auth: Login(
            Match(
              Index("unique_User_email"),
              Var("email")
            ),
            {
              password: Var("password")
            }
          )
        },
        {
          user: Get(
            Select(['instance'], Var('auth'))
          ),
          secret: Select(['secret'], Var('auth'))
        }
      )
    )
  )
});
{
  "errors": [
    {
      "message": "Ref or Set expected, Object provided.",
      "extensions": {
        "code": "invalid argument"
      }
    }
  ]
}

I can’t get the Get to work, not even if I hardcode the Ref(Collection('User'), 'userid') but I can verify that the login works because if I leave out user from the result I actually get the secret.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.