Apollo Server wrapped Resolvers - graphql

A request to Apollo Server with default settings works directly, but not when wrapped in "viewer". Does "viewer" need a custom resolver and how does this resolver know to return from "nextUp" resolver?
query {
nextUp(limit: $limit, eventTypes: $eventTypes) {
eventKey
eventType
distanceMetres
eventDateTime
status
__typename
}
}
above returns valid data structure for nextUp.
below returns null for nextUp.
query {
viewer { # <----------- viewer wrapping nextUp
nextUp(limit: $limit, eventTypes: $eventTypes) {
eventKey
eventType
distanceMetres
eventDateTime
status
__typename
}
}
}
typeDefs:
const typeDefs = gql`
type Event {
eventKey: String
eventType: String
distanceMetres: String
eventDateTime: DateTime!
status: String
}
type ViewerModel {
nextUp(
eventTypes: [String] = null
limit: Int = 0
): [Event]
}
type Query {
viewer: ViewerModel
nextUp(
eventTypes: [String] = null
limit: Int = 0
): [Event]
}
`;
and resolvers:
const nextUp= async (_source: any, _args: IGetNextUpAsync, { dataSources }: any) => {
return dataSources.RestDataSource.getNextUpAsync(_args)
};
const resolvers = {
Query: {
viewer: async (_source: any, _args: any, { dataSources }: any, info: any) => {
return nextUp; // ???
},
nextToGo,
}
};

Related

Cast to ObjectId failed for value \"{ proposser: '618e49a68e18cd48286de4b5' }\" (type Object) at path \"_id\" for model \"Proposal\"

I am getting this error in graphql playground (image below ) .
I have checked for the validity of objectId in the resolver as well.
// model
const ProposalSchema = new Schema({
cover
Letter: {
type: String,
},
budget: {
type: String,
},
proposals: {
type: mongoose.Schema.Types.ObjectId,
},
_id: {
type: mongoose.Schema.Types.ObjectId,
},
});
//resolver
also checked If the argument is valid using mongoose.isValidObjectId(proposser) it returns true
Query: {
proposals(_, args) {
const { proposser } = args;
return Proposal.findById({
proposser,
});
},
},
// schema
const typeDefs = gql`
type Proposal {
_id: ID!
coverLetter: String
budget: String
proposser: ID!
}
`;
const Proposal = mongoose.model("Proposal", ProposalSchema);
I was using wrong method in resolvers .
findById was being used for field non Id field.
async proposals(_, args) {
const { proposser } = args;
const userProposals = await Proposal.find({
proposser,
});
try {
const result = userProposals;
return result ? result : [];
} catch (err) {
console.log(err);
}
},

Access return data from resolver in graphql

I want to access the country field from my resolver. The country is being returned by query but since Product is a list I can only access the object inside items return by query. Is there any way I can have access to whole returned data from query or any way to pass it further down as an argument to my resolver function
//schema
type ProductCollectionPage {
items: [Product!]!
}
//resolver
const resolvers = {
Product: {
variants: async (obj: any, args: any, { dataSources }: any): Promise<IProductVariantPage> => {
const { id } = obj;
// want to access country here
return (dataSources.xyz as XyzRepository).retriveProducts(country, id);
}
},
Query: {
products: async (
obj: any,
{ id }: { id: string },
{ dataSources }: any
): Promise<
any
> => {
const locationDetails = await (dataSources.abc as InventoryLocationsRepository).retrieveInventoryLocation(id);
const country = locationDetails.country;
const response = await (dataSources.abc as XyzRepository).retriveProductIds(country);
// response.list === [{id: 1}, {id:2}]
return {
country,
items: response.list
}
}
}
};
As arrays are objects in javascript then you can just assign additional property to response.list:
response.list.country = country;

GraphQL: Field Resolver Not Firing on Subscription Query?

I've got a subscription query, MessageFolder_Subscription, that looks like this:
QUERY
const MESSAGEFOLDER_SUBSCRIPTION_QUERY = gql`
subscription ($localUserID: String!){
MessageFolder_Subscription(userID: $localUserID){
id
remoteUserData{
id
name_title
name_first
name_last
[...more fields...]
}
},
}
`;
Here's the schema for it:
SCHEMA
type myUserData {
id: String
gender: String
name_title: String
name_first: String
*[...more fields...]*
}
type messageFolder{
id: String
remoteUserData: myUserData
}
type Subscription {
MessageFolder_Subscription(userID: String!): messageFolder
}
Here's how I'm doing the resolvers:
RESOLVERS
const resolvers = {
//FIELD RESOLVER
MessageFolder_Subscription: {
subscribe: withFilter(
() => pubsub.asyncIterator(MSGFOLDER_ADDED_CHANNEL),
(payload, args) => {
debugger; <=== NEVER FIRES
if (typeof (payload) === 'undefined') {
return false;
}
let result = false;
const userId = Meteor.userId();
// let messageFolder = MessageFolder_Subscription.messageFolder;
result = (userId === args.fromID || args === MSGFOLDERargs.toID);
return result;
}
)
},
//ROOT RESOLVER
*[......more resolvers here.....]*
Subscription: {
MessageFolder_Subscription: {
subscribe: withFilter(
() => pubsub.asyncIterator(MSGFOLDER_ADDED_CHANNEL),
(payload, args) => {
debugger;
if (typeof (payload) === 'undefined') {
return false;
}
let result = false;
const userId = Meteor.userId();
// let messageFolder = MessageFolder_Subscription.messageFolder;
result = (userId === args.fromID || args === MSGFOLDERargs.toID);
return result;
}
)
}
}
When I mutate a related item, the MessageFolder_Subscription query is fired by pubsub as expected. Tracing through, I can see that it returns true.
But for some reason, the field resolver, for the field remoteUserData on MessageFolder_Subscription, never fires.
What am I missing?
Solved. I had to add the __typename: field:
const messageFolder_Subscription = {
__typename: 'messageFolder_Subscription',
id: userID,
}
...to the MessageFolder_Subscription subscription object, when it was created in the mutation resolver, prior to being passed to pubsub.

GraphQL Schema and Resolvers organization return null [duplicate]

This question already has answers here:
Why does a GraphQL query return null?
(6 answers)
Closed 3 years ago.
i am toying with the Star Wars API using GraphQL. Using GraphQL Playground, i get null values for the response for the joint entities.
I believe the reason is because of the organization of my schema and resolver files. Below are my codes and the files they are stored in, anyone can help? The current setup only returns the name of the Star Wars character but doesn't return the array of films details under the person/character
Thanks a lot
GQL Playground
{
"data": {
"getPerson": {
"name": "Obi-Wan Kenobi",
"films": [
{
"title": null,
"director": null
}
]
}
}
}
graphql/schema.ts
import { gql } from "apollo-server-express";
export const typeDefs = gql`
type Person {
name: String
height: String
mass: String
homeworld: Planet
films: [Film]
vehicles: [Vehicle]
}
type Planet {
name: String
diameter: String
climate: String
terrain: String
population: String
films: [Film]
}
type Film {
title: String
episode_id: Int
director: String
producer: String
releaseDate: String
}
type Vehicle {
name: String
model: String
manufacturer: String
length: String
crew: String
passengers: String
pilots: [Person]
}
type Query {
getPerson(id: Int!): Person
}
schema {
query: Query
}
`;
graphql/resolvers/index.ts
import PersonResolvers from "./person-resolvers";
export const resolvers = {
Query: {
getPerson: PersonResolvers.getPerson
}
};
graphql/person-resolvers.ts
import fetch from "node-fetch";
export default {
getPerson: async (_: any, { id }: { id: string }) => {
try {
const res = await fetch(`https://swapi.co/api/people/${id}/`);
return res.json();
} catch (error) {
throw error;
}
},
Person: {
films: (person: any) => {
const promises = person.films.map(async (url: string) => {
const res = await fetch(url);
return res.json();
});
return Promise.all(promises);
},
vehicles: (person: any) => {
const promises = person.vehicles.map(async (url: string) => {
const res = await fetch(url);
return res.json();
});
return Promise.all(promises);
}
},
Vehicle: {
pilots: (vehicle: any) => {
const promises = vehicle.pilots.map(async (url: string) => {
const res = await fetch(url);
return res.json();
});
return Promise.all(promises);
}
}
};
I have managed to get it work with this folder organization
For those looking for answers, u can check out my repo below
myhendry gql github repo

GraphQL query ( Apollo client link state ) returns empty object {}

The Query
const GET_MEMBER = gql`
query getMembers {
getMembers #client {
firstname
lastname
__typename
}
}
`
export { GET_MEMBER }
The Resolver:
export default {
resolvers: {
Query: {
getMembers: async (_, variables, { cache }) => {
try {
const res = await apiClient.get('/contacts')
return { ...res.data, __typename: 'Member' }
} catch (e) {
throw e
}
},
},
apiClient is an instance of axios
React App:
<Query query={GET_MEMBER}>
{({ loading, error, data }) => {....
I am getting this warning
and the Query in my React App returns {}
Where should I start to debeg it?

Resources