Hi everybody,
I’m starting with Apollo and hit the following error when defining a new mutation:
“Error: “sendResetPasswordEmail” defined in resolvers, but not in schema” .
Any help will be really appreciated
Below is my schema:
// schema.js
const typeDefs = `
type User {
_id: String
randomString: String
}
type Query {
user: User
}
type Mutation {
sendVerificationEmail: User
sendResetPasswordEmail(email: String!): User
}
`;
export default typeDefs;
Resolvers:
// resolvers.js
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Random } from 'meteor/random';
import { GraphQLError } from 'graphql';
import _ from 'lodash';
const resolvers = {
// We need to tell graphql how to resolve the 'randomString' field inside the
// User query. We could also define resolver functions for the rest of the
// User fields, but if we don't do that graphql will default to the field
// values, which is exactly what we want.
User: {
randomString() {
return Random.id();
},
},
Query: {
user(root, args, context) {
// We access to the current user here thanks to the context. The current
// user is added to the context thanks to the 'meteor/apollo' package.
return context.user;
},
},
Mutation: {
sendVerificationEmail(root, args, context) {
console.log('About to send verification email...');
const { user: curUser } = context;
// User should be logged in at this stage
if (!curUser) {
throw new GraphQLError('User should be logged in at sendVerificationLink');
}
// Make sure the user exists in our database
const curUserId = curUser._id;
const user = Meteor.users.findOne({ _id: curUserId });
if (!user) {
throw new GraphQLError('The user is not registered in our database');
}
if (user.emails[0].verified === true) {
throw new GraphQLError('Email already verified!');
}
try {
Accounts.sendVerificationEmail(curUserId);
} catch (exc) {
console.log(exc);
throw new GraphQLError(`Verification email couldn't be delivered. Reason: ${exc.response}`);
}
console.log('Verification email sent!');
return { _id: curUserId };
},
},
sendResetPasswordEmail(root, args, context) {
console.log('About to send reset password email...');
const { email } = args;
const { user: curUser } = context;
// User shouldn't be logged in at this stage
if (curUser) {
throw new GraphQLError('User shouldn\'t be logged in at sendResetPasswordEmail');
}
// Make sure the user exists in our database
const targetUser = Accounts.findUserByEmail(email);
if (!targetUser) {
throw new GraphQLError('User not found');
}
// Destructure
const { _id: targetUserId, accountDeactivated } = targetUser;
// Prevent user from submitting if account has been deactivated
if (!_.isUndefined(accountDeactivated) && accountDeactivated === true) {
throw new GraphQLError('Account has been Deactivated');
}
try {
Accounts.sendResetPasswordEmail(targetUserId, email);
} catch (exc) {
console.log(exc);
throw new GraphQLError(`Reset password email couldn't be delivered. Reason: ${exc.response}`);
}
console.log('Reset password email sent!');
return { _id: targetUserId };
},
};
export default resolvers;
Apollo server:
import { createApolloServer } from 'meteor/apollo';
import { makeExecutableSchema } from 'graphql-tools';
import typeDefs from '../../api/server/schema.js';
import resolvers from '../../api/server/resolvers.js';
const logger = { log: e => console.error(e.stack) };
const schema = makeExecutableSchema({
typeDefs,
resolvers,
logger,
});
createApolloServer({ schema });
And here is my package.json
{
"name": "meteor-starter-kit",
"private": true,
"scripts": {
"start": "meteor run",
"lint": "eslint --quiet --ext .js,.jsx .",
"prettier": "prettier --write \"client/**/*.js\" \"imports/**/*.js\" \"server/**/*.js\" --single-quote=true --trailing-comma=es5 --print-width=100",
"test": "npm run lint"
},
"dependencies": {
"antd": "^2.13.6",
"apollo-client": "^1.9.3",
"apollo-server-express": "^1.1.3",
"bcrypt": "^0.8.7",
"body-parser": "^1.18.2",
"classnames": "^2.2.5",
"express": "^4.16.1",
"graphql": "^0.11.7",
"graphql-loader": "^1.2.1",
"graphql-tools": "^2.7.1",
"indexof": "0.0.1",
"invariant": "^2.2.2",
"lodash": "^4.17.4",
"meteor-node-stubs": "^0.2.11",
"prop-types": "^15.6.0",
"react": "^15.6.1",
"react-apollo": "^1.4.16",
"react-dom": "^15.6.1",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"recompose": "^0.26.0",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"subscriptions-transport-ws": "^0.5.5",
"tracker-component": "^1.3.21"
},
"devDependencies": {
"autoprefixer": "^6.3.5",
"babel-eslint": "^7.0.0",
"babel-plugin-import": "^1.1.0",
"babel-preset-stage-1": "^6.16.0",
"eslint": "^2.10.2",
"eslint-config-airbnb": "^9.0.1",
"eslint-import-resolver-meteor": "^0.4.0",
"eslint-plugin-import": "^1.8.0",
"eslint-plugin-jest": "^21.2.0",
"eslint-plugin-jsx-a11y": "^1.2.0",
"eslint-plugin-meteor": "^3.5.2",
"eslint-plugin-react": "^5.1.1",
"node-sass": "^3.4.2",
"postcss-reporter": "^1.3.3",
"redux-devtools": "^3.3.2",
"redux-devtools-dock-monitor": "^1.1.1",
"redux-devtools-log-monitor": "^1.2.0",
"stylelint": "^5.2.1"
}
}