PROBLEM
the mutation below
mutation {
signUp(signUpInput: {email: "[email protected]", username: "newUser", password: "asdfasdfawerawer"}) {
email
username
}
}
errors out the following
{
"errors": [
{
"message": "Cannot query field \"email\" on type \"SignUpResponse\".",
"locations": [
{
"line": 3,
"column": 5
}
]
},
{
"message": "Cannot query field \"username\" on type \"SignUpResponse\".",
"locations": [
{
"line": 4,
"column": 5
}
]
}
]
}
EXPECTATION
{
"data": {
"signUp": {
"email": "[email protected]",
"username": "newUser"
}
}
}
snippets of code
schema.graphql snippet
...
input SignUpInput {
username: String!
email: String!
password: String!
}
type Mutation {
signUp(signUpInput: SignUpInput): SignUpResponse!
}
type SignUpResponse {
ok: Boolean!
error: String
addedUser: User
}
resolvers.go snippet
...
// UserResolver ingests properties from User
type UserResolver struct{ u *User }
// UserID returns the userId of the user
func (r *UserResolver) UserID() graphql.ID {
return r.u.UserID
}
// Username returns the username of the user
func (r *UserResolver) Username() string {
return r.u.Username
}
// Email returns the email of the user
func (r *UserResolver) Email() string {
return r.u.Email
}
// Password returns the password of the user
func (r *UserResolver) Password() string {
return r.u.Password
}
type SignUpArgs struct {
Username string
Email string
Password string
}
// SignUp returns a new User from Db and its responses
func (r *RootResolver) SignUp(args struct{ SignUpInput *SignUpArgs }) (*SignUpResolver, error) {
// Find user:
u, err := r.Db.CreateUser(args.SignUpInput)
// need to deal with this different, so sort of error if we can't create the user
// a. user already exists
// b. email already exists
if err != nil {
// error creating the user
msg := "already signed up"
return &SignUpResolver{
Status: false,
Msg: &msg,
User: nil,
}, err
}
return &SignUpResolver{
Status: true,
Msg: nil,
User: &UserResolver{&u},
}, nil
}
// SignUpResolver is the response type
type SignUpResolver struct {
Status bool
Msg *string
User *UserResolver
}
// Ok for SignUpResponse
func (r *SignUpResolver) Ok() bool {
return r.Status
}
// Error for SignUpResponse
func (r *SignUpResolver) Error() *string {
return r.Msg
}
// AddedUser for SignUpResponse
func (r *SignUpResolver) AddedUser() *UserResolver {
return r.User
}
postgres.go - db operations
// User returns a single user
func (d *Db) User(uid graphql.ID) (User, error) {
var (
sqlStatement = `SELECT * FROM users WHERE user_id=$1;`
row *sql.Row
err error
u User
)
row = d.QueryRow(sqlStatement, uid)
err = row.Scan(
&u.UserID,
&u.Username,
&u.Email,
&u.Password,
)
util.Check(err, "row.Scan")
return u, nil
}
// CreateUser - inserts a new user
func (d *Db) CreateUser(i *SignUpArgs) (User, error) {
var (
sqlStatement = `
INSERT INTO users (email, username, password)
VALUES ($1, $2, $3)
RETURNING user_id`
userID graphql.ID
row *sql.Row
err error
u User
)
/***************************************************************************
* retrieve the UserID of the newly inserted record
* db.Exec() requires the Result interface with the
LastInsertId() method which relies on a returned value from postgresQL
* lib/pq does not however return the last inserted record
****************************************************************************/
row = d.QueryRow(sqlStatement, i.Email, i.Username, i.Password)
if err = row.Scan(&userID); err != nil {
// err: username or email is not unqiue --> user already exsits
return u, err
}
u, _ = d.User(userID)
return u, nil
}
I've tried to change the CreateUser to this
// CreateUser - inserts a new user
func (d *Db) CreateUser(i *SignUpArgs) (User, error) {
var (
sqlStatement = `
INSERT INTO users (email, username, password)
VALUES ($1, $2, $3)
RETURNING user_id`
userID graphql.ID
row *sql.Row
err error
u User
)
/***************************************************************************
* retrieve the UserID of the newly inserted record
* db.Exec() requires the Result interface with the
LastInsertId() method which relies on a returned value from postgresQL
* lib/pq does not however return the last inserted record
****************************************************************************/
row = d.QueryRow(sqlStatement, i.Email, i.Username, i.Password)
if err = row.Scan(&userID); err != nil {
// err: username or email is not unqiue --> user already exsits
return u, err
}
err = row.Scan(
&u.UserID,
&u.Username,
&u.Email,
&u.Password,
)
util.Check(err, "row.Scan User")
return u, nil
}
didn't do it obviously. hence the question, why the query error? seems like UserResolver can't return the User data provided the row is being returned from db.
Your type definitions include:
It appears you're attempting to query the fields for the returned
User, butsignUpdoes not return aUserobject. Instead,signUpreturns aSignUpResponseobject, which, as the error states, does not have any fields namedemailorusername.The correct query would look something like this: