Unable to get result of productByHandle query when nil when using shopify_api with graphql query - ruby

I am trying to retrieve the result from a graphQL query when the product is nil by using the productByHandle query, but it's erroring out.
My code in Ruby:
client = ShopifyAPI::GraphQL.client
product_handle_query = client.parse <<-'GRAPHQL'
query ($productHandle: String!) {
productByHandle(handle: $productHandle) {
id
handle
title
tags
productType
vendor
}
}
GRAPHQL
result = client.query(product_handle_query, variables: {productHandle: productHandle})
puts result.data.productByHandle
This should return nil, but when I try and message out, it returns with this error:
NoMethodError (undefined method `productByHandle' for #< productByHandle=nil>)
This query works fine in Insomnia, where the output looks like this:
{
"data": {
"productByHandle": null
},
"extensions": {
"cost": {
"requestedQueryCost": 1,
"actualQueryCost": 1,
"throttleStatus": {
"maximumAvailable": 2000.0,
"currentlyAvailable": 1999,
"restoreRate": 100.0
}
}
}
}
I have also tried changing from String! (which is not-null type which is what is returning) to String, but I get this error:
GraphQL::Client::ValidationError (Nullability mismatch on variable $productHandle and argument handle (String / String!))
My variable for $productHandle is indeed a string, so not sure why this isn't working either.
Any help would be appreciated.
Thanks!

Figured out how to read the result from the output above:
result.original_hash["data"]["productByHandle"]
This returns nil and allows me to continue to create a new product.

Related

Conditional field in GraphQL Where query

Using Apollo client I am trying to run a query that will return students with any status if the status field is empty. If there is a status filter it should be applied:
const statusWhere = inputs.status ? { equals: $inputs.status }: {};
query GetStudents($course: ID, $status: String, $statusWhere: status_bool_exp) {
studentCourses (where :{
status: {$statusWhere},
course: {
id: {
equals: $course
}
},
# other fields, etc
This is giving error:
GraphQLError: Syntax Error: Expected Name, found "$".
Could you provide any hints?
After a bunch of trial and error I was able to figure it out myself. Posting it here because it could be useful for someone else.
Using the regular JS string interpolation variables works here.
So you need to define the condition as a string literal:
const statusWhere = inputs.status ? 'equals: "'+ inputs.status +'"' : '';
Then the whole gpl string looks like this:
gql`
query GetStudents($course: ID) {
studentCourses (where :{
status: {
${statusWhere}
},
course: {
id: {
equals: $course
}
},
})
# fields etc`
In this case you do not need to pass your string variable as a query param.

How to pass object type argument in query in GraphQL?

I got this type of query
query {
searchRandom (param : MyObjectClass){
city
}
}
How may I set param with the type of MyObjectClass and pass it in the query? To be able to test here?
Use the following query.
query getData($param: MyObjectClass){
searchRandom(param: $param)
city
}
And then go to query variables tab in Graphiql and pass the variable data like this. You have not mention the data types included in MyObjectClass. So use this as an example:
{
"param": {"country": "England", "population": "High" }
}
Then the data should be returned as expected.
--- Additionally ---
If you are running the server, make sure you have set the followings.
You need to create a input object in the GraphQL schema.
input MyObjectClass {
country: String
population: String
}
Then in the resolver you have to pass the object as the argument. (Assuming you are using JavaScript)
const resolvers = {
Query: {
searchRandom: (parent, { param }) => {
var query_data = param
...//your code
return city_name;
},
},
I am not sure whether this addresses your question or not. I hope this answer helps though.

GraphQL doesn't consider dynamic arrays of strings valid strings

I have a query that works when manually typed:
queryName(where: { ids: ["1234567890123456789", "1234567890123456790"] }, offset: 0, max: 10) {
but when the same values are passed in a variable:
const idArr = ["1234567890123456789", "1234567890123456790"];
...
queryName(where: { ids: ${idArr} }, offset: 0, max: 10) {
I get the error:
Uncaught GraphQLError: Syntax Error: Expected Name, found Int "1234567890123456789"
Can anyone explain this?
Using string interpolation like that will result in the following value being inserted inside your string:
"1234567890123456789,1234567890123456790"
This is not valid GraphQL syntax and so results in a syntax error. Instead of using string interpolation, you should use GraphQL variables to provide dynamic values along with your query:
query ($idArr: [ID!]!) {
queryName(where: { ids: $idArr }, offset: 0, max: 10) {
...
}
}
Note that the type of the variable will depend on the argument where it's being used, which depends on whatever schema you're actually querying.
How you include the variables along with your request depends on the client you're using to make that request, which is not clear from your post. If you're using fetch or some other simple HTTP client, you just include the variables alongside the query as another property in the payload you send to the server:
{
"query": "...",
"variables": {
...
}
}

I get a GraphQL error when running this query using the apollo server. Anyone one knows what is the problem with it?

I am trying to fetch some data from the GitHub GraphQL but I get a GaphQLError. I have tried the same query on the developer section of github and it works. Anyone know what is the problem with it?
issueQuery = gql`
query search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
node {
... on Issue {
createdAt
title
body
url
comments(first: 10) {
nodes {
body
}
}
}
}
}
}
`;
Error Stack Trace:
"GraphQLError: Syntax Error: Expected $, found Name "first"
at syntaxError (http://localhost:4200/vendor.js:70270:10)
at expect (http://localhost:4200/vendor.js:75154:67)
at parseVariable (http://localhost:4200/vendor.js:73984:3)
at parseVariableDefinition (http://localhost:4200/vendor.js:73970:15)
at many (http://localhost:4200/vendor.js:75222:16)
at parseVariableDefinitions (http://localhost:4200/vendor.js:73959:82)
at parseOperationDefinition (http://localhost:4200/vendor.js:73926:26)
at parseExecutableDefinition (http://localhost:4200/vendor.js:73881:16)
at parseDefinition (http://localhost:4200/vendor.js:73845:16)
at many (http://localhost:4200/vendor.js:75222:16)"
New Error Stack Trace when adding $ before the parameters:
"GraphQLError: Syntax Error: Expected Name, found Int "10"
at syntaxError (http://localhost:4200/vendor.js:70270:10)
at expect (http://localhost:4200/vendor.js:75154:67)
at parseName (http://localhost:4200/vendor.js:73809:15)
at parseNamedType (http://localhost:4200/vendor.js:74385:11)
at parseTypeReference (http://localhost:4200/vendor.js:74364:12)
at parseVariableDefinition (http://localhost:4200/vendor.js:73971:83)
at many (http://localhost:4200/vendor.js:75222:16)
at parseVariableDefinitions (http://localhost:4200/vendor.js:73959:82)
at parseOperationDefinition (http://localhost:4200/vendor.js:73926:26)
at parseExecutableDefinition (http://localhost:4200/vendor.js:73881:16)"
Don't confuse the operation with the actual field being queried. The syntax should look like this:
operationType [operationName] [variableDefinitions] {
selectionSet
}
where operationType is one of query, mutation or subscription, operationName is an arbitrary name for your operation used in debugging, variableDefinitions are type definitions for any variables you reference inside the operation, and selectionSet is one or more fields you're actually querying.
In this case, search is a field we're querying, so it should not be proceeded by the query keyword. This works fine, provided you're authenticated:
query OptionalName {
search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
# more fields
}
}
}
If the operation type is query, you can omit the query keyword altogether. This is called "query shorthand":
{
search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
# more fields
}
}
}
If you use variables, define them inside parentheses beside your operation. Variable names are arbitrary, but by convention we use the input field names they will be used in:
query OptionalName ($first: Int, type: SearchType!, $query: String! ) {
search(first: $first, type: $type, query: $query) {
issueCount
edges {
# more fields
}
}
}

Resolving query type with promise in bucklescript

I've got this query im trying to test with with the reason graphql_ppx library. code gist
This is a screenshot of the editor type annotations:
Using the #mhallin/graphql_ppx library, i've got the following query set up:
module FilmQuery = [%graphql
{|
{
allFilms {
films {
id
title
releaseDate
}
}
}
|}
];
exception Graphql_error(string);
/* Construct a "packaged" query; FilmQuery takes no arguments: */
let filmQuery = FilmQuery.make();
/* Send this query string to the server */
let query = filmQuery##query // type string
I get an the following error when i send the query to the server it returns the following error.
{ errors: [ { message: 'Must provide query string.' } ] }
But if you Js.log(query) you see its being constructed which works on https://swapi.apis.guru
query films($first: Int) {
allFilms(first: $first) {
films {
id
title
releaseDate
}
}
}
If you Js.log(filmQuery) you get:
{ query: 'query {\nallFilms {\nfilms {\nid \ntitle \nreleaseDate \n}\n}\n}',
variables: null,
parse: [Function: parse] }
If your run the same query in Altair and you check the query that was sent in the devtools network tab you see:
{"query":" query films($first: Int) {\n allFilms(first: $first) {\n films {\n id\n title\n releaseDate\n }\n }\n }\n","variables":{}}
The editor is provided this type error:
"- error
[bucklescript]
This has type:
string
But somewhere wanted:
Js.t({.. query : string, variables : Js.Json.t })
string"
How do I get this promise/unit type resolved? Thank you.
So the new question is: Why isn't the sendQuery() function recognizing the filmQuery##parse key?
Your sendQuery method is expecting a type in the shape of what is returned from FilmQuery.make(), but you are passing it just the query property, which is a string.
You can fix this by passing filmQuery as into sendQuery instead of just the query property from filmQuery that is referenced by the query variable.

Resources