GraphQL: Variable is used by anonymous query but not declared - graphql

I am new to GraphQL. I have a query, but it shows error message of "Variable is used by anonymous query but not declared".
{
"query":"{customers(first: 1, query: $input) {edges{node {addresses{ id }}}}}",
"variables":{
"input":{
"id":"gid://shopify/Customer/5044061470926"
}
}
}
Can I get some help what I did wrong?
Thanks!

The error is correct. Your query is
{
customers(first: 1, query: $input) {
edges{
node {
addresses{
id
}
}
}
}
}
and $input is indeed not declared, so GraphQL has no idea what it is supposed to be or how to link it up with your variables values.
You'll need to do
query ($input: <THE_TYPE>!) {
customers(first: 1, query: $input) {
edges{
node {
addresses{
id
}
}
}
}
}
I don't know your API schema, so you'll have to replace <THE_TYPE> with whatever type is defined in your API schema.

Related

Shopify Admin API, graphQL, create draft order - add products

This is my fist time creating an order. From what I understand you need to create a draft order - add products, price, email, notes etc. I am just creating a test query now to see how it works and it tells me "Add at least 1 product". I am trying to add a product, but I dont know how. I have been messing around and reading and cant figure it out.
This is my query:
mutation draftOrderCreate {
draftOrderCreate(input: {email: "123abc#hotmail.com"}) {
draftOrder {
id
order {
id
}
status
}
userErrors {
field
message
}
}
}
If anyone can give me an example on how to add products to this would be great. Thanks.
You can create an draft order like so:
mutation draftOrderCreate($items: DraftOrderInput!) {
draftOrderCreate(input: $items) {
draftOrder {
id
order {
id
}
status
}
userErrors {
field
message
}
}
}
query variables:
{
"items": {
"email": "123abc#hotmail.com",
"lineItems": [
{
"variantId": "gid://shopify/ProductVariant/32231002996788",
"quantity": 1
}
]
}
}
Or if you don't want to use query variables you can pass the whole object as the input:
mutation draftOrderCreate {
draftOrderCreate(input: {email: "123abc#hotmail.com", lineItems: [{variantId: "gid://shopify/ProductVariant/32231002996788", quantity: 1}]}) {
draftOrder {
id
order {
id
}
status
}
userErrors {
field
message
}
}
}

GraphQL / Strapi - Can not filter by string field

According to the GraphQL docs, it should be as simple as:
query Link($slug: String) {
link(slug: $slug) {
slug
}
}
But I am getting Error: unknown field slug
I have searched other answers and other docs, and tried the following queries as well:
"Unknown argument "where" on field "link" of type "Query".
query Link($slug: String) {
link(where: {slug: $slug}) {
slug
}
}
Error: Unknown argument "where" on field "link" of type "Query".
{
link: link(where: { slug: "a" }) {
slug
}
}
For Strapi v4, I think they removed where. So, I make it work with filters.
query Links($id: String) {
links(filters: { slug: {eq: $id}}) {
data{
attributes{
slug,
title
}
}
Finally after much more examining the docs, I was able to get the following query to work:
query Links($id: String) {
links(where: { slug: $id }) {
slug
}
}

Store error: the application attempted to write an object with no provided typename but the store already contains an object

After mutation when I am updating the cache, changes are reflected in UI but getting the below error
Invariant Violation: Store error: the application attempted to write an object with no provided typename but the store already contains an object with typename of ItemCodeConnection for the object of id $ROOT_QUERY.itemCodes({"filter":{"number":10000001}}). The selectionSet that was trying to be written is:
{"kind":"Field","name":{"kind":"Name","value":"itemCodes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"itemCodes"},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"itemCodeTile"},"directives":[]},{"kind":"Field","name":{"kind":"Name","value":"__typename"}}]}},{"kind":"Field","name":{"kind":"Name","value":"__typename"}}]}}
GraphQL query:
const CREATE_ITEM_CODE_SPEC = gql`
mutation createItemCodeSpec($input: createItemCodeSpecInput) {
createItemCodeSpecification(input: $input){
__typename
id
itemCode {
number
}
product
spec_class
grade
}
}
`
const GET_ITEM_CODE = gql`
query itemCode($filter: filterInput){
itemCodes(filter: $filter){
itemCodes {
number
type
description
group
item_code_spec {
id
itemCode {
number
}
product
spec_class
grade
}
created_on
created_by
changed_on
changed_by
}
}
}
`
Below is the mutation:
const [mutation, { data, loading, error}] = useMutation(
CREATE_ITEM_CODE_SPEC,
{
update(cache, { data: { createItemCodeSpecification } }){
const currentData = cache.readQuery({
query: GET_ITEM_CODE,
variables: { filter : {number:itemCode} }
})
cache.writeQuery({
query: GET_ITEM_CODE,
variables: { filter : {number:itemCode} },
data: {
...currentData,
itemCodes: {
itemCodes: currentData.itemCodes.itemCodes.map((itemCode, index) => {
return {
...itemCode,
item_code_spec: index === 0? [
...itemCode.item_code_spec,
createItemCodeSpecification
] : itemCode.item_code_spec
}
})
}
}
})
}
}
);
You simply need to add "id" for each subsection of your query. Adding "id" for "itemCodes" in your GET_ITEM_CODE query might solve your problem.
You have fields missing in your response mutation.
Basically, you should make your mutation results have all of the data necessary to update the queries previously fetched.
That’s also why is a best practice to use fragments to share fields among all queries and mutations that are related.
To make it work both query and mutation should have exactly the same fields.
Have a look here to see more in depth how cache updates work:
https://medium.com/free-code-camp/how-to-update-the-apollo-clients-cache-after-a-mutation-79a0df79b840

Apollo Query with param

I would like to add parameter on Query using react-apollo.
My actual query is this :
const GET_USER_PLAYIST = gql`
query Playlist($id: ID!) {
playlists(where: { users: { id: $id } }) {
name
users {
id
}
}
}
`;
But it doesn't work (i receive error 400 :/). But, with "static" query, it works as expected :
{
playlists(where: { users: { id: $id } }) {
name
users {
id
}
}
I do not really understand why it doesn't work with query params.
Anyone can help me?
Thank you community!

Relay mutation fragments intersection

I don't use Relay container, because I'd like to have more control over components. Instead of it I use HOC + Relay.Store.forceFetch, that fetches any given query with variables. So I have the following query:
query {
root {
search(filter: $filter) {
selectors {
_id,
data {
title,
status
}
},
selectorGroups {
_id,
data {
title,
}
}
}
}
}
Then I have to do some mutation on selector type.
export default class ChangeStatusMutation extends Relay.Mutation {
getMutation() {
return Relay.QL`mutation {selectors_status_mutation}`;
}
getVariables() {
return {
id: this.props.id,
status: this.props.status
};
}
getFatQuery() {
return Relay.QL`
fragment on selectors_status_mutationPayload{
result {
data {
status
}
}
}
`;
}
static fragments = {
result: () => Relay.QL`
fragment on selector {
_id,
data {
title,
status
}
}`,
};
getOptimisticResponse() {
return {
result: {
_id: this.props.id,
data: {
status: this.props.status
}
}
};
}
getConfigs() {
return [{
type: 'FIELDS_CHANGE',
fieldIDs: {
result: this.props.id
},
}];
}
}
Call mutation in component:
const mutation = new ChangeStatusMutation({id, status, result: selector});
Relay.Store.commitUpdate(mutation);
After mutation commitment selector in Relay storage is not changed. I guess that's because of empty Tracked Fragment Query and mutation performs without any fields:
ChangeStatusMutation($input_0:selectors_statusInput!) {
selectors_status_mutation(input:$input_0) {
clientMutationId
}
}
But the modifying selector was already fetched by Relay, and I pass it to the mutation with props. So Relay knows the type, that should be changed, how to find the item and which fields should be replaced. But can not intersect. What's wrong?
So, you're definitely a bit "off the ranch" here by avoiding Relay container, but I think this should still work...
Relay performs the query intersection by looking up the node indicated by your FIELDS_CHANGE config. In this case, your fieldIDs points it at the result node with ID this.props.id.
Are you sure you have a node with that ID in your store? I'm noticing that in your forceFetch query you fetch some kind of alternative _id but not actually fetching id. Relay requires an id field to be present on anything that you later want to refetch or use the declarative mutation API on...
I'd start by checking the query you're sending to fetch whatever this result type is. I don't see you fetching that anywhere in your question description, so I'm just assuming that maybe you aren't fetching that right now?

Resources