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.
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.