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;
}
}
Related
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);
}
I have a GraphQL mutation that adds a book. I want to check if the author given exists yet and if not, add that author with a different mutation. Is this possible?
Mutation: {
addAuthor: (root, args) => {
const author = { ...args, id: uuid() }
authors = authors.concat(author)
return author
},
addBook: (root, args) => {
const existingAuthor = authors.filter(author => author.name === args.author).length > 0
if (!existingAuthor) {
addAuthor({ name: args.author }) /// This is how I want to call a mutation within my mutation
}
const book = { ...args, id: uuid() }
books = books.concat(book)
return book
}
}
Right now, this approach throws an error from the Apollo Studio Explorer:
"path": [
"addBook"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"ReferenceError: addAuthor is not defined"
Factor out your addAuthor function and use it in both places:
Mutation: {
addAuthor: _addAuthor,
addBook: (_, args) => {
const existingAuthor = authors.findIndex((a) => a.name === args.author) > -1;
if (!existingAuthor) _addAuthor(null,{ name: args.author });
const book = { ...args, id: uuid() }
books = books.concat(book)
return book
}
}
const _addAuthor = (_, args) => {
const author = { ...args, id: uuid() }
authors = authors.concat(author)
return author
}
This is my test code snippet but it throws an exception, TypeError: componentInstance.loadLoanApplication is not a function :
it('should render the SubmittedLoan', () => {
const loanData = {
data: {
id: 1,
};
const div = document.createElement('div');
const wrapper = mount(
<AppProviders>
<MemoryRouter initialEntries={['/review/153']}>
<SubmittedLoan
match={{ params: { loanId: 1, step: 1 } }}
history={{
location: { state: { from: 'register' } },
push() {},
}}
/>
</MemoryRouter>
</AppProviders>,
div,
);
const componentInstance = wrapper
.find(SubmittedLoan)
.children()
.first()
.children()
.first()
.instance();
const loanApplication = {
id: 1,
steps_data: [
{ slug: 'step_1', title: 'Step 1' },
{ slug: 'step_2', title: 'Step 2' },
],
status: ApiCaptiq.STATUS_SUBMITTED,
};
expect(wrapper.find(SubmittedLoan).length).toBe(1);
componentInstance.loadLoanApplication(1, 1);
componentInstance.onLoadLoanApplication(loanData);
componentInstance.onLoadFail();
componentInstance.setState({
formData: [{ item: 'value' }, { item2: 'value2' }],
activeStep: 1,
loanApplication,
});
componentInstance.handleSnackbarClose(new Event('click'), '');
componentInstance.setState({ activeStep: 3 });
});
Then my Component which uses memo is as follows :
export const SubmittedLoan = memo(() => {
const [loanApplication, setLoanApplication] = useState<LoanApplication | null>(null);
const [message, setMessage] = useState({
message: '',
open: false,
messageType: '',
});
const authContext = useContext(AuthContext);
const customerContext = useCustomerData();
const params = useParams();
const history = useHistory();
const classes = useStyles();
const { loanId } = params;
const onLoadFail = useCallback(() => {
setMessage({
message: 'Die verfügbaren Darlehensarten können nicht aufgelistet werden',
open: true,
messageType: 'error',
});
}, []);
const onLoadLoanApplication = useCallback(
(response: AxiosResponse) => {
setTemplateSettings(response, authContext);
if (
response.data.status === ApiCaptiq.STATUS_STARTING ||
response.data.status === ApiCaptiq.STATUS_IN_PROGRESS ||
response.data.status === ApiCaptiq.STATUS_PRE_WAITING
) {
history.push(`/view/${loanId}`);
} else {
setLoanApplication(response.data);
}
},
[loanId, authContext, history],
);
const loadLoanApplication = useCallback(
async (loan_id: number) => {
try {
const response = await request.get(`${ApiCaptiq.LOAN_APPLICATION_URL}${loan_id}/`);
const { fetchCustomerProfile } = customerContext;
await fetchCustomerProfile(response.data.customer_profile_id);
onLoadLoanApplication(response);
} catch (err) {
onLoadFail();
}
},
[customerContext, onLoadLoanApplication, onLoadFail],
);
...
What could be the possible reason for this
The functions you are defining inside the component, are not just available on the component instance. In fact, there is not way to call them. You can test only by mocking the fetch calls they are doing.
If you really need callable functions in your component (you should try to avoid these..), you could use this: https://reactjs.org/docs/hooks-reference.html#useimperativehandle
Perhaps better would be to extract this data loading logic elsewhere and test it separately.
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:
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"
}
]
}
}
}