I am trying to bulk update the price on multiple product variants at once. I'm just copying the "interactive" example from Shopify's page
All I did was copy and paste the code and put in my own id's. And of course it does not work.
It looks like this:
mutation productVariantsBulkUpdate($variants: [ProductVariantsBulkInput!]!, $productId: ID!) {
productVariantsBulkUpdate(variants: $variants, productId: $productId) {
product {
cursor
}
productVariants {
cursor
}
userErrors {
code
field
message
}
}
}
With Variables like this:
{
"variants": [
{
id: "gid://shopify/ProductVariant/39369514385591",
price: "50.00"
}
],
"productId": "gid://shopify/Product/6591908577463"
}
I'm getting this error:
Variables are invalid JSON: Unexpected token i in JSON at position 30.
It's OK for me. (with some quick tweaks)
I tweaked the request a little since the cursor is not present in the product/variant object, don't know why Shopify has not updated the example in their docs.
mutation productVariantsBulkUpdate($variants: [ProductVariantsBulkInput!]!, $productId: ID!) {
productVariantsBulkUpdate(variants: $variants, productId: $productId) {
product {
id
}
productVariants {
id
price
}
userErrors {
code
field
message
}
}
}
So try to fix the query and remove the cursor object and check if you are using the proper end-point since the bulk operation is available in the unstable version only if I'm not mistaken.
See the image below showing that the response is OK for me.
Related
Im having trouble with my Shopify Function where I want to give a discount on the products if the client chooses pickup. Is there a way to get if the client picked PICK_UP as the delivery option ? I tried looking into this option HERE, but the response from shopify comes back empty does not matter if I choose shipping option or a pickup option. Here is my input query:
query Input {
cart {
lines {
quantity
merchandise {
__typename
...on ProductVariant {
id
}
}
}
deliveryGroups {
selectedDeliveryOption {
deliveryMethodType
}
}
}
discountNode {
metafield(namespace: "this", key: "that") {
value
}
}
}
Am I doing anything wrong? Any ideas what I could try?
In my application I am searching for products, then clicking into a product to see more detail about it.
I perform a GraphQL query on each page. The SEARCH query returns type [Product], and the PRODUCT query returns type Product.
// Search page
const SEARCH = gql`
query Search($query: String!) {
searchResults: search(query: $query) {
id
name
images
price
}
}
`
// ProductDetail page
const PRODUCT = gql`
query Product($id: Int!) {
product(id: $id) {
id
name
images
optionSetName
options {
id
images
name
}
price
}
}
`
I have enabled returnPartialData on the PRODUCT query, as some of the fields for that product already exist in the cache from the SEARCH query, and I would like to access them before the server request returns.
I thought I would also have to apply a field policy to reference the pre-existing Product, as I don't know how PRODUCT even knows what its return type is.
However, when I do the following:
const { loading, data: { product } = {} } = useQuery(
PRODUCT,
{ variables: { id: productId, isShallow }, returnPartialData: true }
)
console.log(product)
the following is logged to console (the first is from returnPartialData, the second from server):
Somehow the PRODUCT query has associated itself with the existing Product, without me explicitly writing a cache redirect.
I'm confused how this has occurred? It seems like Apollo must have a reference to the GraphQL schema, and has seen the return type of PRODUCT is Product, then automatically used the id arg to reference the existing product.
Using "#apollo/client": "^3.4.1"
Wow, turns out I had made a field policy ages ago and forgotten about it... xD
typePolicies: {
Query: {
fields: {
product: {
read (_, { args, toReference }) {
return toReference({
__typename: 'Product',
id: args.id
})
}
}
}
}
}
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
}
}
}
I'm totally new to both Shopify Storefront API AND GraphQL. I've been pulling my hair out the last 3-4 hours reading through docs and trying to find and write a query that, in my mind anyways, should be simple.
In a nutsell, I have a storefront that has certain products included on it with custom buy buttons. Each buy button's ID corresponds with the product ID on my actual shopify store, meaning ../products/5854987878567
When the page loads, I need to query my store to pull the updated prices, and then reflect those prices in the button text so the person has an accurate idea of how much they are spending.
To do this, I've pulled all unique button ID's and pushed them to a fresh Array, the idea being I can query all ID's at once using GraphQL and get one nice object back that I can then parse and update the buttons accordingly.
After hours of going in circles, I haven't gotten any closer to succeeding.
I've been reading the Query Root documentation and it seems like they do have the products connection, which I assume serves as the entry point to query all products on the store.
However under the query field itself it seems like they have every field BUT id.
available_for_sale
created_at
product_type
tag
title
updated_at
variants.price
vendor
Are all the fields they have. Since I started writing this I found sortKey, but it failed with the error "Field 'sortKey' doesn't exist on type 'QueryRoot'" sigh.
Here is my query that I'm currently rolling with. I'm not sure this idea will work because if I can only query one id at a time that'll take dozens of API calls per visitor.
$.ajax({
type : 'POST',
url : 'https://xxxxx.myshopify.com/api/2020-10/graphql.json',
headers: {
'X-Shopify-Storefront-Access-Token': 'xxxxx',
'Content-Type': 'application/graphql'
},
data: 'query products { sortKey(id: "5854987878567") }',
success: function(res) {
console.log(res)
},
error: function(status) {
console.log(status)
}
});
Any help would be appreciated!
I don't understand what you mean but the GraphQL below gets "id", "title", "description", "the first image" and "price" for each product(10 products):
{
products(first:10) {
edges {
node {
id
title
description
featuredImage {
url
}
variants(first: 1) {
edges {
node {
priceV2 {
amount
}
}
}
}
}
}
}
}
query = '''
{
productVariants(first:1,query:"title:%s")
{
edges
{
node
{
id
title
}
}
}
}
''' % title
make a function and give 'title' as a argument.
def productvariant(title):
client = shopify.GraphQL()
query = '''
{
productVariants(first:1,query:"title:%s")
{
edges
{
node
{
id
title
}
}
}
}
''' % title
you can get the price from product variant just like this - "{
productVariants(first:10, query:"{apply your condition here}") {
edges
{
node
{
storefrontId
compareAtPrice
price
}
} } } % id"
I have a GraphQL query called myAccounts which returns an array of accounts. When I go to the Playground and call the query:
{
accounts {
email
}
}
I get this result:
"data": {
"accounts": [
{
"email": "zach#email-one.com",
},
{
"email": "zach#email-two.com",
}
]
}
However, when I am in my Component, vue-apollo returns two items in the array, but seems to overwrite the second item with the first. Here is the query (in MyAccounts.gql):
query myAccounts {
accounts: myAccounts {
email
}
}
and here is the Apollo query in the component:
import MY_ACCOUNTS_QUERY from '~/apollo/queries/MyAccounts'
...
apollo: {
accounts: {
query: MY_ACCOUNTS_QUERY,
result(data) {
console.log(JSON.stringify(data))
}
}
}
and here is what vue-apollo logs out through the result:
{
"data":{
"accounts":[
{
"email":"zach#email-one.com",
"__typename":"Account"
},
{
"email":"zach#email-one.com",
"__typename":"Account"
}
]
},
"loading":false,
"networkStatus":7,
"stale":false
}
Expected behavior
I would expect the data returned in the Playground to be identical to what vue-apollo is fetching.
Versions
vue: 2.6.10
vue-apollo: #nuxtjs/apollo: 4.0.0-rc18
Additional context
I thought the result hook would be the best way to debug, but any other suggestions gladly welcomed. I assumed that this was a bug in our code, but I cannot figure out what could be causing the repetition (and mismatch).
Apollo normalizes its cache based on the __typename and the id (or _id) field. You need to include an id or _id field in your selection set alongside email. Failing to do so results in both objects being assigned the same key. If you don't have an id field to request, you'll need to provide a custom dataIdFromObject function as shown here.
From Guillaume Chau (https://github.com/Akryum):
This is because the Apollo Client cache can't compute a different ID
for the two items, so you endup with Account:undefined (or similar)
for both. Open the Apollo devtools and look at the myAccounts key in
the cache.
Learn more:
https://www.apollographql.com/docs/react/caching/cache-configuration/