A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
I need to update a product
I did check Graphiql and the query does produce data. I will double check the permissions but it does not work
index.js
import { useCallback, useMemo, useState } from "react";
import { Button, Card, DataTable, EmptyState, Frame, Heading, Page, Stack, TextField, Toast } from "@shopify/polaris";
import { ResourcePicker } from "@shopify/app-bridge-react";
import { useMutation } from "react-apollo";
import { ProductUpdateMutation } from "../graphql/productUpdate";
const Index = () => {
const [appendToTitle, setAppendToTitle] = useState('');
const [appendToDescription, setAppendToDescription] = useState('');
const [products, setProducts] = useState([]);
const [showToast, setShowToast] = useState(false);
const [pickerOpen, setPickerOpen] = useState(false);
const [updateProduct]= useMutation(ProductUpdateMutation);
const productPickerHandler = useCallback(() => setPickerOpen(true), []);
const productTableDisplayData = useMemo(() => products.map((product) => [
product.id,
product.title,
`${product.title}${appendToTitle}`,
]), [products, appendToTitle]);
const submitHandler = useCallback(() => {
let count = 0;
const runMutation = (product) => {
updateProduct({
variables:{
input: {
title:"testnn",
id: "gid://shopify/Product/7327935889643"
}
}
}).then((data) => {
console.log('update Product', count, data);
count++;
if (products[count]) runMutation(products[count])
else {
console.log('Updates Complete');
setShowToast(true);
}
})
}
runMutation(products[count]);
},[products, appendToTitle, appendToDescription]);
const toastMarkup = showToast ?
<Toast
content="update successful"
onDismiss={() => setShowToast(false)}
duration={4000}
/> : null;
return (
<Frame>
<Page>
<Heading>Update your products</Heading>
<Card>
<Card.Section>
<Stack vertical>
<TextField
label="Append to title"
value={appendToTitle}
onChange={setAppendToTitle}
/>
<ResourcePicker
resourceType="Product"
showVariant={false}
open={pickerOpen}
onSelection={(resources) => {
setProducts(resources.selection);
console.log(products);
}}
/>
<Button primary onClick={productPickerHandler} > Select products </Button>
</Stack>
</Card.Section>
<Card.Section>
{productTableDisplayData.length ?
<DataTable
columnContentTypes={['text', 'text', 'text']}
headings={['id', 'Old Title', 'New Title']}
rows={[productTableDisplayData]}
/>
:
<EmptyState heading="No products selected" />}
</Card.Section>
<Card.Section>
<Button primary onClick={submitHandler} disabled={!products.length}> Submit changes </Button>
</Card.Section>
</Card>
{toastMarkup}
</Page>
</Frame>
)
};
export default Index;
app.js
import ApolloClient from "apollo-client";
import { ApolloProvider } from "react-apollo";
import App from "next/app";
import { AppProvider } from "@shopify/polaris";
import { Provider, useAppBridge } from "@shopify/app-bridge-react";
import { authenticatedFetch, getSessionToken } from "@shopify/app-bridge-utils";
import { Redirect } from "@shopify/app-bridge/actions";
import "@shopify/polaris/dist/styles.css";
import translations from "@shopify/polaris/locales/en.json";
import { createHttpLink } from "@apollo/client";
import { InMemoryCache } from "apollo-cache-inmemory";
function userLoggedInFetch(app) {
const fetchFunction = authenticatedFetch(app);
return async (uri, options) => {
const response = await fetchFunction(uri, options);
if (
response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
) {
const authUrlHeader = response.headers.get(
"X-Shopify-API-Request-Failure-Reauthorize-Url"
);
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
return null;
}
return response;
};
}
function MyProvider(props) {
const app = useAppBridge();
const client = new ApolloClient({
link: new createHttpLink({
uri:'https://test-app.myshopify.com/api/2021-07/graphql.json',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token':process.env.Access-Token ,
}
}),
fetchOptions: {
credentials: 'include',
},
cache: new InMemoryCache(),
})
const Component = props.Component;
return (
<ApolloProvider client={client}>
<Component {...props} />
</ApolloProvider>
);
}
class MyApp extends App {
render() {
const { Component, pageProps, host } = this.props;
return (
<AppProvider i18n={translations}>
<Provider
config={{
apiKey: API_KEY,
host: host,
forceRedirect: true,
}}
>
<MyProvider Component={Component} {...pageProps} />
</Provider>
</AppProvider>
);
}
}
MyApp.getInitialProps = async ({ ctx }) => {
return {
host: ctx.query.host,
};
};
export default MyApp;
productUpdate.js
import { gql } from "graphql-tag";
export const ProductUpdateMutation = gql `
mutation productUpdate($input: ProductInput!) {
productUpdate(input: $input) {
userErrors {
field
message
}
product {
id
description
title
}
}
}
`;
Hi @nazeli
Could you please post the output of the query as it is being sent to Shopify?
Thanks!
To learn more visit the Shopify Help Center or the Community Blog.
the objective of my request is to change the title of the product
my request work in graphql
i change my request in index.js
import { useCallback, useMemo, useState } from "react";
import { Button, Card, DataTable, EmptyState, Frame, Heading, Page, Stack, TextField, Toast } from "@shopify/polaris";
import { ResourcePicker } from "@shopify/app-bridge-react";
import { useMutation } from "react-apollo";
import { useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
//////////////////////////////////////////////////
const updte=gql`
mutation {
productUpdate(input:{id:"gid://shopify/Product/7327935889643",title:"test3"}) {
userErrors {
field
message
}
product {
id
title
}
}
}
`;
//////////////////////////////////////////////////
const Index = () => {
const [products] =useMutation(updte)
return (
------------------
)
};
export default Index;
but if i test my app i don't get any error and at the same time the query doesn't work