Finding one element in graphQL by id/email - javascript

I'm trying to make a findOneByEmail/id for graphQL. I saw a couple of questions, blog posts, and videos, but they didn't help my case. I know I have to add a filter, but I have to be missing something
Here are my resolvers
const users = [
{id: 1, email:'a#a.a',password:'zaq1#WSX', pons:[{value:'test'}]},
{id: 2, email:'b#b.b',password:'ZAQ!2wsx', pons:[{value:'tset'}]}
];
const pons = [{value: 'test'}];
module.exports = {
Query: {
users: () => users,
pons: () => pons,
}
};
typeDefs
const {gql} = require('apollo-server-express');
module.exports = gql`
type Pon {
value: String!
}
type User {
id: Int
email: String!
password: String!
pons: [Pon]!
}
type Query {
findUser(id: Int): [User]
users: [User]
pons: [Pon]
}
`;
app.js
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const typeDefs = require('./graphql/typeDefs.js');
const resolvers = require('./graphql/resolvers.js');
const server = new ApolloServer({typeDefs, resolvers});
const app = express();
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () =>
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
);
I am using express with apollo-server-express.
I tried adding users(id: Int) and users(email: String), but with no success. You can see it in findUser query. I am calling the query like:
query{
findUser(id: 1) {
email
pons {
value
}
}
}
In the GQL playground.
I'd like to able to filter the data on the server, not on the client, and can't find the solution anywhere

You can get the id parameters in GraphQL resolver and query user by it.
E.g.
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const { gql } = require('apollo-server-express');
const users = [
{ id: 1, email: 'a#a.a', password: 'zaq1#WSX', pons: [{ value: 'test' }] },
{ id: 2, email: 'b#b.b', password: 'ZAQ!2wsx', pons: [{ value: 'tset' }] },
];
const pons = [{ value: 'test' }];
const typeDefs = gql`
type Pon {
value: String!
}
type User {
id: Int
email: String!
password: String!
pons: [Pon]!
}
type Query {
findUser(id: Int): User
users: [User]
pons: [Pon]
}
`;
const resolvers = {
Query: {
users: () => users,
pons: () => pons,
findUser: (_, { id }) => users.find((u) => u.id === id),
},
};
const server = new ApolloServer({ typeDefs, resolvers });
const app = express();
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () => console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`));
query in GraphQL playground:
query{
findUser(id: 1){
email
pons {
value
}
}
}
response:
{
"data": {
"findUser": {
"email": "a#a.a",
"pons": [
{
"value": "test"
}
]
}
}
}

Related

Graphql doesn't return the data

I'm trying to find a specific data based on the id in graphql.
But it is returning null .
I have also tried the mutation. Here is also it is returning null.
What's wrong with this below code.
const { ApolloServer } = require("#apollo/server");
const { startStandaloneServer } = require("#apollo/server/standalone");
const students = [
{
name: "langesh",
roll: 131,
},
{
name: "ram",
roll: 134,
},
];
const typeDefs = `#graphql
type Student {
name: String,
roll: Int,
}
type Query {
students: [Student]
student(roll: Int) : Student
}
`;
const resolvers = {
Query: {
students: () => students,
student: (parent, roll) => {
return students.find((s) => s.roll === roll);
},
},
};
const server = new ApolloServer({ typeDefs, resolvers });
async function startServer() {
const { url } = await startStandaloneServer(server, {
listen: {
port: 8000,
},
});
console.log(`url : ${url}`);
}
startServer();
You need to destructure the args in your resolver.
Instead of:
student: (parent, roll) => {
return students.find((s) => s.roll === roll);
}
do:
student: (parent, { roll }) => {
return students.find((s) => s.roll === roll);
}

Inherit resolvers from graphql interface with Apollo Server v3

I would like to inherit resolvers from a graphql interface.
Consider this schema.
const typeDefs = gql`
interface Name {
name: String!
surname: String!
}
type Person implements Name {
_id: ID!
name: String!
surname: String!
}
type Query {
getPerson: Person!
}
}
And these resolvers:
const queryResolver = {
Name: {
name: () => "John",
surname: () => "Doe"
},
Query: {
getPerson: async (parent, args, context, info) => {
return {
_id: "1",
};
},
}
}
This is my server
const { ApolloServer } = require("apollo-server");
const typeDefs = require("./types");
const queryResolvers = require("./resolvers/query");
const resolvers = {
Query: queryResolvers.Query,
Name: queryResolvers.Name,
};
try {
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen().then(({ url }) => {
console.log(`Apollo server listening on ${url}`);
});
} catch (e) {
console.error(e);
}
I would like that when querying the server
query Query {
getPerson {
name
surname
}
}
I get John Doe, as I would expect that Person inherits the resolvers from Name.
On ApolloServer v.2 I get this functionality implemented through inheritResolversFromInterfaces https://www.apollographql.com/docs/apollo-server/v2/api/graphql-tools/
I have not been able to find and equivalent on ApolloServer v3.0
The only option I could find is by creating the schema by using makeExecutableSchema from the #graphql-tools/schema, and then passing that schema to the ApolloServer constructor:
const schema = makeExecutableSchema({
typeDefs,
resolvers,
inheritResolversFromInterfaces: true,
});
const server = new ApolloServer({
...otherApolloArguments,
schema,
});

[Error: Query.Mutation defined in resolvers, but not in schema]

const { ApolloServer, gql } = require('apollo-server-express');
const express = require('express');
const port = process.env.PORT || 4000;
const notes = [
{ id: '1', content: 'This is a note', author: 'Adam Scott' },
{ id: '2', content: 'This is another note', author: 'Harlow Everly' },
{ id: '3', content: 'Oh hey look, another note!', author: 'Riley Harrison' }
];
const typeDefs = gql `
type Note {
id: ID
content: String
author: String
}
type Query {
hello: String
notes: [Note]
note(id: ID!): Note
}
type Mutation {
newNote(content: String!): Note
}
`;
const resolvers = {
Query:{
hello: () => 'Hello World',
notes: () => notes,
note: (parent, args) => {
return notes.find(note => note.id == args.id);
},
Mutation: {
newNote: (parent, args) => {
let noteValue = {
id : String(notes.length + 1),
content : args.content,
author: 'Adam Scott',
};
notes.push(noteValue);
return noteValue;
}
}
},
}
Some people had naming issues but seems that I'm using the same in resolver as well as in schema.
Please bare with me, this is my second day in GraphQL and Express. I removed intentionally imports and assignment of express object, middleware since it does not let me post.
I think you are simply missing a curly bracket.
const resolvers = {
Query:{
hello: () => 'Hello World',
notes: () => notes,
note: (parent, args) => {
return notes.find(note => note.id == args.id);
}
}, <==== THIS IS MISSING =====>
Mutation: {
newNote: (parent, args) => {
let noteValue = {
id : String(notes.length + 1),
content : args.content,
author: 'Adam Scott',
};
notes.push(noteValue);
return noteValue;
}
}

TypeError when Mocking a Node Module with Jest

Here I have a file, mail.js, that sends an email
const nodemailer = require('nodemailer')
const mailGun = require('nodemailer-mailgun-transport')
const auth = {
auth: {
api_key: process.env.MAILGUN_API_KEY,
domain: process.env.DOMAIN
}
}
const transporter = nodemailer.createTransport(mailGun(auth))
const mailTo = (name, email) => {
const mailOptions = {
from: 'example#icloud.com',
to: 'cm#example.com',
subject: 'Welcome!',
text: `Hey, ${name}! Thanks for joining Task Manager!`
}
transporter.sendMail(mailOptions)
}
module.exports = mailTo
I am trying to do Jest tests and I need to mock the nodemailer and mailGun functions so I don't get an email every time I run a test. So I made a __mocks__ folder and put my 2 mock modules in it at __mocks__/nodemailer.js and __mocks__/nodemailer-mailgun-transport.js. Here are those files
//nodemailer.js
module.exports = {
createTransport() {
},
sendMail() {
}
}
//nodemailer-mailgun-transport.js
module.exports = {
mailGun() {
}
}
And here are my tests
const request = require('supertest')
const jwt = require('jsonwebtoken')
const mongoose = require('mongoose')
const app = require('../src/app')
const User = require('../src/models/user')
const userOneId = mongoose.Types.ObjectId()
const userOne = {
_id: userOneId,
name: 'Jon',
email: 'jon#example.com',
password: 'JonTest123',
tokens: [{
token: jwt.sign({ _id: userOneId }, process.env.JWT_SECRET)
}]
}
beforeEach(async () => {
await User.deleteMany()
await new User(userOne).save()
})
test('Should signup a new user', async() => {
const response = await request(app).post('/users').send({
name: 'Caleb',
email: 'caleb#example.com',
password: 'TestPass637!'
}).expect(201)
//Assert that the database was changed correctly
const user = await User.findById(response.body.user._id)
expect(user).not.toBeNull()
//Assertions about the response
expect(response.body).toMatchObject({
user: {
name: 'Caleb',
email: 'caleb#example.com'
},
token: user.tokens[0].token
})
expect(user.password).not.toBe('TestPass637!')
})
And I have Jest setup to look for the __mocks__ file in the tests directory, which is where I have it
But when I run my tests, I get
TypeError: mailGun is not a function
Why doesn't it recognize the mailGun() function?
The nodemailer-mailgun-transport should return a function so that you can pass the auth to it. In your test code mailGun refers to the default output, not a property.
//nodemailer-mailgun-transport.js
module.exports = (auth) => {
// do something with auth, if you want
}

Apollo GraphQL - resolver not being triggered

I'm new to GraphQL. I started with the Javascript Apollo library and cannot get a resolver to fire. It's hard for me to tell when resolvers should be called, and what key I should put.
Here's my schema and resolvers:
// The GraphQL schema in string form
const typeDefs = `
type Query { user(id: ID!): User, posts: Post }
type User { id: ID!, created: Int, username: String, bio: String, status: String, avatar: String, posts: [Post] }
type Post { id: ID!, created: Int, user_id: Int, text: String, object_set_id: Int, edited: Int, views: Int, upvotes: Int, downvotes: Int, Parent: Int }
`;
// The resolvers
const resolvers = {
Query: {
user: (parent, args, context, info) => {
return users.find(user => user.id === Number(args.id));
},
// posts: () => posts,
},
Post: {
id: (parent, args, context, info) => {
console.log(posts.filter(post => post.user_id === Number(parent.id)))
return posts.filter(post => post.user_id === Number(parent.id))
}
}
};
I want to specify a user by their user ID, then filter down to get all the posts that user has made (eventually with a time filter).
I've tried several things, but 'posts' under a user always comes up 'null'. What am I missing? Thanks.
User (Or more semantic: userById) query
Your first query works fine.
You should also add some data(Otherwise you get an error "message": "users is not defined",).
Execute query:
query{
user(id: 1){
id
username
}
}
Basic code example:
const { ApolloServer, gql } = require("apollo-server");
const users = [
{
id: 1,
username: "Kate Chopin"
},
{
id: 2,
username: "Paul Auster"
}
];
// The GraphQL schema in string form
const typeDefs = gql`
type Query {
userById(id: ID!): User
}
type User {
id: ID!
username: String
}
`;
// The resolvers
const resolvers = {
Query: {
userById: (parent, args, context, info) => {
return users.find((user) => user.id === Number(args.id));
}
}
};
const server = new ApolloServer({
typeDefs,
resolvers
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
posts query (Or more semantic: postById):
About posts - your query is posts and no resolver match + looks like you do a little "salad" their.
It is better to follow this example (Same idea only books/authors instead of posts/user):
https://www.apollographql.com/docs/apollo-server/getting-started/
Next, read this Resolver chains: https://www.apollographql.com/docs/apollo-server/data/resolvers/#resolver-chains
Again hello world example
const posts = [
{
id: 1,
name: "Article One"
},
{
id: 2,
name: "Article Two"
}
];
const users = [
{
id: 1,
username: "Kate Chopin",
posts: posts
},
{
id: 2,
username: "Paul Auster"
}
];
// The GraphQL schema in string form
const typeDefs = gql`
type Query {
userById(id: ID!): User
}
type User {
id: ID!
username: String
posts: [Post]
}
type Post {
id: ID!
name: String
}
`;
// The resolvers
const resolvers = {
Query: {
userById: (parent, args, context, info) => {
return users.find((user) => user.id === Number(args.id));
}
}
};
const server = new ApolloServer({
typeDefs,
resolvers
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Query:

Categories