sdy
sdy

Reputation: 355

GraphQL always return null

I created a resolver and graphql file about user creation.
The data type seems to fit, and I have asynchronous processing, but the result always return null. I don't know why.

import { prisma, generateToken, changePhoneNumber } from "../../../utils";
import bcrypt from "bcryptjs";

export default {
  Mutation: {
    createAccount: async (_, args) => {
      const {
        username,
        password,
        password2,
        email,
        phoneNum,
        bio,
        avatarUrl,
      } = args;

      if (password !== password2) {
        throw new Error("two password aren't same each other");
      }

      const encryptPw = await bcrypt.hash(password, 10);
      const newPhoneNumber = await changePhoneNumber(phoneNum, "+82");
      const user = await prisma.user.create({
        data: {
          username,
          email,
          password: encryptPw,
          phoneNum: newPhoneNumber,
          bio,
          avatarUrl,
        },
      });
      const token = generateToken(user.id);

      return { token, user };
    },
  },
};

type Mutation {
  createAccount(
    username: String!
    email: String!
    password: String!
    password2: String!
    phoneNum: String!
    bio: String
    avatarUrl: String
  ): AuthPayload!
}


type AuthPayload {
  token: String
  user: User
}

import { PrismaClient } from "@prisma/client";
import jwt from "jsonwebtoken";

export const prisma = new PrismaClient();

export const changePhoneNumber = (phoneNum, locationNum) => {
  var leftStr = locationNum;
  var rightStr = phoneNum.slice(1, phoneNum.length);
  var newStr = leftStr + rightStr;
  return newStr;
};

export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET);
type User {
  id: ID!
  avatarUrl: String
  username: String!
  email: String!
  password: String!
  phoneNum: String!
  emailSecret: String
  phoneSecret: String
  bio: String
  rooms: [Room]
  createdAt: String
  messages: [Message]
  sender: [User]
  receiver: [User]
}

I read the answers to other similar questions, but most said that I should fit the data type or asynchronous processing.
(Why does a GraphQL query return null?)
But my code used code for asynchronous processing, and I guess I matched the data type. Why does this code always return null? enter image description here
Also, in addition to this Mutation, all other Query, Mutation and Subscriptions return nulls

Upvotes: 2

Views: 2000

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84857

Based on the error, it looks like GraphQL doesn't think you've provided a resolver for the createAccount field at all. The issue is with how you're merging your resolvers. This is your code:

const allTypes = fileLoader(path.join(__dirname, "api/**/*.graphql"));
const allResolvers = fileLoader(path.join(__dirname, "api/**/*.js"));

const schema = makeExecutableSchema({
  typeDefs: mergeTypes(allTypes),
  resolvers: mergeResolvers(allResolvers),
});

This is the resulting value of allResolvers:

[ { Query: { TestQL: [Function: TestQL] } },
  { Mutation: { addCategory: [Function: addCategory] } },
  { Mutation: { deleteCategory: [Function: deleteCategory] } },
  { Mutation: { editCategory: [Function: editCategory] } },
  { Mutation: { newMessage: [Function: newMessage] } },
  { Subscription: { subMessage: [Object] } },
  [Function: _default],
  { Mutation: { createRoom: [Function: createRoom] } },
  [Function: _default],
  { Query: { getRooms: [Function: getRooms] } },
  { Mutation: { createAccount: [Function: createAccount] } },
  { Mutation: { deleteUser: [Function: deleteUser] } },
  { Mutation: { editProfile: [Function: editProfile] } },
  { Query: { findEmail: [Function: findEmail] } },
  { Mutation: { login: [Function: login] } },
  { Mutation: { requestEmailSecret: [Function: requestEmailSecret] } },
  { Mutation: { resetPassword: [Function: resetPassword] } },
  { Query: { searchUser: [Function: searchUser] } },
  { Query: { seeProfile: [Function: seeProfile] } } ]

Two of your modules export a function instead of an object:

export default () => {...}

As a result, what's returned by mergeResolvers ends up being a function, not an object. So you're not providing a resolver map at all to makeExecutableSchema. You need to fix the default exports for those two modules for the resolvers to be merged correctly.

Upvotes: 2

Related Questions