must have a selection of subfields. Did you mean \"createEvent { ... }\"?", [graphql] [duplicate] - mongodb

Hi I am trying to learn GraphQL language. I have below snippet of code.
// Welcome to Launchpad!
// Log in to edit and save pads, run queries in GraphiQL on the right.
// Click "Download" above to get a zip with a standalone Node.js server.
// See docs and examples at https://github.com/apollographql/awesome-launchpad
// graphql-tools combines a schema string with resolvers.
import { makeExecutableSchema } from 'graphql-tools';
// Construct a schema, using GraphQL schema language
const typeDefs = `
type User {
name: String!
age: Int!
}
type Query {
me: User
}
`;
const user = { name: 'Williams', age: 26};
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
me: (root, args, context) => {
return user;
},
},
};
// Required: Export the GraphQL.js schema object as "schema"
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
// Optional: Export a function to get context from the request. It accepts two
// parameters - headers (lowercased http headers) and secrets (secrets defined
// in secrets section). It must return an object (or a promise resolving to it).
export function context(headers, secrets) {
return {
headers,
secrets,
};
};
// Optional: Export a root value to be passed during execution
// export const rootValue = {};
// Optional: Export a root function, that returns root to be passed
// during execution, accepting headers and secrets. It can return a
// promise. rootFunction takes precedence over rootValue.
// export function rootFunction(headers, secrets) {
// return {
// headers,
// secrets,
// };
// };
Request:
{
me
}
Response:
{
"errors": [
{
"message": "Field \"me\" of type \"User\" must have a selection of subfields. Did you mean \"me { ... }\"?",
"locations": [
{
"line": 4,
"column": 3
}
]
}
]
}
Does anyone know what I am doing wrong ? How to fix it ?

From the docs:
A GraphQL object type has a name and fields, but at some point those
fields have to resolve to some concrete data. That's where the scalar
types come in: they represent the leaves of the query.
GraphQL requires that you construct your queries in a way that only returns concrete data. Each field has to ultimately resolve to one or more scalars (or enums). That means you cannot just request a field that resolves to a type without also indicating which fields of that type you want to get back.
That's what the error message you received is telling you -- you requested a User type, but you didn't tell GraphQL at least one field to get back from that type.
To fix it, just change your request to include name like this:
{
me {
name
}
}
... or age. Or both. You cannot, however, request a specific type and expect GraphQL to provide all the fields for it -- you will always have to provide a selection (one or more) of fields for that type.

Related

How to update composite type model in Prisma?

I am trying to implement updation in a composite-type model in Prisma.
Here is my data structure:
{
"name":"toy",
"data":{
"sports":{
"currentState":"false"
},
"business":{
"currentState":"false"
}
}
}
Here I my code for updating:
const updatedSource = await prisma.sources.update({
where: {
name: 'toy'
},
data: {
data: {
sports: {
currentState: "true"
}
}
},
})
Here is my schema file
type SourcesData {
business SourcesDataState
sports SourcesDataState
}
type SourcesDataState {
currentState StateData[]
}
type StateData {
title String
url String
}
model sources {
id String #id #default(auto()) #map("_id") #db.ObjectId
data SourcesData
name String #unique
}
When I execute the above logic I get error as:Unknown arg `sports` in data.data.sports for type SourcesDataUpdateEnvelopeInput. Did you mean `set`? Available args:
Please guide what I am missing while updating.
The TypeScript should be pretty helpful in telling you what arguments you can or cannot use when interacting with Prisma. I strongly recommend using a code editor that includes TypeScript typehinting/Intellisense so you can see errors and warnings about your TypeScript usage as you are developing with Prisma.
Where it says Available args in your error, that should tell you the arguments that prisma.sports.update actually expects. If I had to guess (this may not be accurate, but you HAVE to look at the TypeScript to know exactly what it's supposed to be), it should look something like this:
const updatedSource = await prisma.sources.update({
where: {
name: 'toy'
},
data: {
data: {
update: {
sports: {
update: {
currentState: {
set: ["true"]
}
}
}
}
}
},
})
I strongly recommend reading Prisma's documentation on updating related/nested records: https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#update-a-specific-related-record
let typeEncounter = await prisma.encounter.update({
where: {
id
},
data: {
[property]: {
update: {
[subProperty] : value,
},
},
},
}
)
I get a receive the error Unknown arg update in data..update
I have seen some people mention nesting updates but no official documentation and can't seem to get this straightened out. Anybody have any ideas? The property and subproperty are largely irrelevant here, just examples. The code works fine aside from updated a subfield of a type (mongoDB prisma). Without the update the entire type gets overwritten rather than the selected field.

Prisma Typescript where clause inside include?

I am trying to query the database (Postgres) through Prisma. My query is
const products = await prisma.products.findMany({
where: { category: ProductsCategoryEnum[category] },
include: {
vehicles: {
include: {
manufacturers: { name: { in: { manufacturers.map(item => `"${item}"`) } } },
},
},
},
});
The error message is
Type '{ name: { in: { manufacturers: string; "": any; }; }; }' is not assignable to type 'boolean | manufacturersArgs'.
Object literal may only specify known properties, and 'name' does not exist in type 'manufacturersArgs'.ts(2322)
Manufacturers have the field name and it is unique; I am not sure why this is not working or how I can update this code to be able to query the database. It is like I should cast the values into Prisma arguments.
The TypeScript error is pretty self-explanatory: the name property does not exist in manufacturersArgs. The emitted Prisma Client does a great job of telling you what properties do and do not exist when filtering.
If you are trying to perform a nested filter, you need to use select instead of include.
Documentation: https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#filter-a-list-of-relations
Your query is going to look something like this:
const products = await prisma.products.findMany({
where: { category: ProductsCategoryEnum[category] },
select: {
// also need to select any other fields you need here
vehicles: {
// Updated this
select: { manufacturers: true },
// Updated this to add an explicit "where" clause
where: {
manufacturers: { name: { in: { manufacturers.map(item => `"${item}"`) } } },
},
},
},
});
The final code ultimately depends on your Prisma schema. If you are using an editor like VS Code, it should provide Intellisense into the Prisma Client's TypeScript definitions. You can use that to navigate the full Prisma Client and construct your query based on exactly what is and is not available. In VS Code, hold control [Windows] or command [macOS] and click on findMany in prisma.products.findMany. This lets you browse the full Prisma Client and construct your query!
The in keyword isn't working for me. I use hasSome to find items in an array. hasEvery is also available depending what the requirements are.
hasSome: manufacturers.map(item => `"${item}"`),
See https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#scalar-list-filters

Schema mutation for deleteMany({})

I have this simple resolver:
removeAllMovies: () => {
return prisma.movie.deleteMany({});
},
When I run my apollo client I get an error:
Mutation.removeAllMovies defined in resolvers, but not in schema
So I want to add the mutation to the schema but I can't find the correct syntax. I want to remove all the movies, not based on a id or a filter:
type Mutation {
removeAllMovies()
}
This shows an error while starting the Apollo server:
Syntax Error: Expected Name, found ")".
What's the correct schema syntax for a deleteMany({}) resolver?
This should do it:
type BatchPayload {
count: Int!
}
type Mutation {
removeAllMovies: BatchPayload
}
And the resolver is correct so no changes there.

How to define parameters/arguments to a list resolver?

I have this schema and the corresponding resolvers:
const schema = buildSchema(
`
type Query {
posts(id: Int): [Post]
}
type Post {
id: Int!,
title: String,
date: String
}`
);
const resolvers = {
posts(root, { id }, context, info) {
console.log(id); // Undefined
return [
{
id: 0,
date: '21/04/2018',
title: 'Post 1'
},
{
id: 1,
date: '07/10/2018',
title: 'Post 2'
}
];
},
Post(postObj) {
return {
id: postObj.id,
title: postObj.title,
date: postObj.date
}
}
}
The problem is that when I query for posts with an specified id, like this:
query {
posts(id: 0) {
title
}
}
... I get an error that says I haven't defined such argument (id).
I defined the id argument according to the GraphQL Docs. Any suggestions of what may be causing this error and how to solve it?
When you use buildSchema, you effectively prevent yourself from being able to define custom resolvers for a given field in your schema. Instead, the default resolver will always be used. The default resolver simply takes the "parent" or "root" object for a given field, looks up the property on that parent object with the same name as the field and returns its value.
You can "get away" with this for simpler schemas by passing in a root object along with your schema. This root object then becomes the parent object referenced by the default resolver, but only for top level fields (like each field you define for your Query type). So in this case, when GraphQL resolves your query, the default resolver sees a posts property on the parent object and returns that. Because posts is actually a function, it calls the function first and then returns the value, but the arguments it calls it with are not the same arguments that a resolver is called with.
Resolvers receive four parameters -- 1) the "root" or "parent" value, 2) arguments, 3) context and 4) an "info" object containing additional data about the request. Any function called by the default resolver will only get the last 3 parameters (so no "root" value).
In other words, you should change your root object to look more like this:
const root = {
posts({ id }, context, info) {
return [
{
id: 0,
date: '21/04/2018',
title: 'Post 1'
},
{
id: 1,
date: '07/10/2018',
title: 'Post 2'
}
];
},
}
However, does it this way will only let you handle top-level fields like queries. You will not be able to customize resolver behavior for fields on other types, like Post. To do that, you should use graphql-tools' makeExecutableSchema.

Github GraphQL API: How can I find out which fields are searchable?

When I run the query:
{
"query": "{user(login: \"furknyavuz\") {repositories(first: 50, isPrivate: false) {nodes {name url}}}}"
}
I getting the following error:
{
"data": null,
"errors": [
{
"message": "Field 'repositories' doesn't accept argument 'isPrivate'",
"locations": [
{
"line": 1,
"column": 51
}
]
}
]
}
I can see isPivate is field of Repository object but I'm unable to search with it.
I'm not expecting to search with all fields of the object, but critical question is, how can I see which fields are searchable or indexable?
isPrivate is a field of Repository object but repositories inside User object is of type RepositoryConnection and repositories connection item has the following argument/type :
affiliations [RepositoryAffiliation]
after String
before String
first Int
isFork Boolean
isLocked Boolean
last Int
orderBy RepositoryOrder
privacy RepositoryPrivacy
RepositoryPrivacy is an enum with two values : PUBLIC and PRIVATE.
the following request will return private repo :
{
user(login: "furknyavuz") {
repositories(first: 50, privacy:PRIVATE) {
nodes {
name
url
}
}
}
}
Note that in the explorer, if you type CTRL+space you will have the schema listing with types :
Also, CTRL+space again after ":" will gives you the enum values :
Autocomplete:
Navigate to Github's GraphQL API Explorer. This is a GraphiQL interface that lets you write your queries and run in them in real time. One of the neat features of GraphiQL is that includes an auto-complete feature. When you're typing the arguments for a field, just press Alt+Space or Shift+Space and a list of possible arguments will pop up. This works for fields too.
The docs:
You can also view the documentation for the schema by hitting the Docs link in the upper right corner of the interface. This will bring up a list of all possible fields, including what arguments they take. There's also a schema reference page here.
GraphQL:
Lastly, you can actually just ask the GraphQL endpoint yourself. For example, running this query will list all types for the schema and the arguments used by each one:
{
__schema {
types {
name
inputFields {
name
description
type {
name
}
defaultValue
}
}
}
}