I'm very new to programming with react/javascript/node. I'm using Shopify CLI and generated a boilerplate app that uses react/next.js/apollo.
I don't know if I'm using the right approach for what I want to achieve. I'm basically trying to update my app's database of the merchants store information when they log in.
My logic will be:
- Merchant logs into app.
- My app will check database and see if data is more than 24 hours old.
- If so it'll sync the data to ensure the app is up to date.
- I don't need to display anything if successful but I do want to display an error if either the graphql fails or the database update fails.
So far I'm just testing the graphql side. I created a function that retrieves the data from shopify via grapql. This seems to be working as I get the data back and if I add an error to the graphql I get the error return.
I want to display a shopify polaris banner when they get an error. I've tried various ways to do this from my google searches but haven't found the proper approach.
In the code below I get the banner display when there's an error however because it was rendered through the return of the function the dismiss doesn't work. I am unable to find a way to have it display the error while allowing it to be dismissed by the merchant.
function QueryShopifyStoreInfo() {
const { loading, error, data } = useQuery(GET_STORE_INFORMATION);
if (loading) return null;
if (error) return (
<Layout.Section>
<Banner title="Error Syncing with Shopify" status="critical" onDismiss={activeUpdateError}>
<p>There was an error syncing your store data with Shopify. We have been notified of the error and will investigate. This does not impact the functionality of the app. You can continue to use the app as normal.</p>
<p>If you continue to receive this error, please send us a message.</p>
</Banner>
</Layout.Section>
);
return (
null
);
}
I apologize for my lack of knowledge. I'm using this app with going through various courses on react/javascript to learn. I appreciate your feedback.
Update (for comment below):
I cleaned it up a bit but here's the code so far for index.js
import React, {useState, useCallback, Fragment} from 'react';
import gql from 'graphql-tag';
import { useQuery } from 'react-apollo';
import {
Layout,
Page,
Card,
Banner,
} from '@shopify/polaris';
export default function App() {
// Setup useStates
const [active, setActive] = useState(false);
const [UpdateErrorActive, setUpdateErrorActive] = useState(false);
// Setup Variables
//let UpdateErrorActive = false; // Error Syncing Shopify Data
// Setup Handles/useCallBacks
// Setup Toggle Callbacks
const toggleActive = useCallback(
() => {
setActive(!true);
},
[true],
);
// Toggle Update Error to Active
const activeUpdateError = useCallback(
() => {
setUpdateErrorActive(!true);
},
[true],
);
// Setup Breakcrumbs, Primary, Secondary Actions (if needed)
// Setup Item Lists (choiceListItems in Polaris Sample)
// Setup Changeable Texts based on status
// const accountSectionDescription = connected
// ? 'Disconnect your account from your Shopify store.'
// : 'Connect your account to your Shopify store.';
// Setup Return Markups for Display
// const shopifyUpdateStatusMarkup = UpdateErrorActive ? (
// <Layout.Section><Banner title="Error Syncing with Shopify" status="critical" onDismiss={activeUpdateError}>
// <p>There was an error syncing your store data with Shopify. We have been notified of the error and will investigate. This does not impact the functionality of the app. You can continue to use the app as normal.</p>
// <p>If you continue to receive this error, please send us a message.</p>
// </Banner></Layout.Section>
// ) : (
// null
// );
// Shopify GraphQL Query
const GET_STORE_INFORMATION = gql`
query {
shop {
id
name
email
contactEmail
description
myshopifyDomain
url
plan{
displayName
partnerDevelopment
}
}
}
`;
// Functions
// Retrieve Shopify Shop Information and update database.
function QueryShopifyStoreInfo() {
const { loading, error, data } = useQuery(GET_STORE_INFORMATION);
if (loading) return null;
if (error) return (
<Layout.Section>
<Banner title="Error Syncing with Shopify" status="critical" onDismiss={activeUpdateError}>
<p>There was an error syncing your store data with Shopify. We have been notified of the error and will investigate. This does not impact the functionality of the app. You can continue to use the app as normal.</p>
<p>If you continue to receive this error, please send us a message.</p>
</Banner>
</Layout.Section>
);
console.log("Get Store Information - data:")
console.log(data);
const shopID = data.shop.id;
const shopName = data.shop.name;
const email = data.shop.email;
const contactEmail = data.shop.contactEmail;
const description = data.shop.description;
const myshopifyDomain = data.shop.myshopifyDomain;
const url = data.shop.url;
const planDisplayName = data.shop.plan.displayName;
const partnerDevelopment = data.shop.plan.partnerDevelopment;
console.log("partnerDevelopment", partnerDevelopment);
return (
null
);
}
return (
<Page
fullWidth
title="My Title"
>
<Layout>
<QueryShopifyStoreInfo />
{/* {shopifyUpdateStatusMarkup} */}
<Layout.Section>
<Card title="Online store dashboard" sectioned>
<p>Lots of text here to go with this card.</p>
</Card>
</Layout.Section>
</Layout>
</Page>
);
}
Now the only thing is that the page generated with the Shopify CLI has it setup to create classes like this:
class FindA extends React.Component {
state = {
discount: '10%',
};
render() {
const { discount } = this.state;
return (
<Page>
<Layout>
<Layout.AnnotatedSection
title="Test - Find A Page"
description="Add a product to Sample App, it will automatically be discounted."
>
<Card sectioned>
<Form onSubmit={this.handleSubmit}>
<FormLayout>
<TextField
value={discount}
onChange={this.handleChange('discount')}
label="Discount percentage"
type="discount"
/>
<Stack distribution="trailing">
<Button primary submit>
Save
</Button>
</Stack>
</FormLayout>
</Form>
</Card>
</Layout.AnnotatedSection>
</Layout>
</Page>
);
}
handleSubmit = () => {
this.setState({
discount: this.state.discount,
});
console.log('submission', this.state);
};
handleChange = (field) => {
return (value) => this.setState({ [field]: value });
};
}
export default FindA;
The above is just a test page from another page to test routes. It serves no purpose but you can see that it's using the class instead of a function like the app. The function used in index.js was copied from shopify's react-app next.js example on github. This might be completely inappropriate to use in this type of app.
export default function App() {
Any guidance on how I should do this so that it's proper react/javascript is appreciated.
Basically my goal is to just query a mongodb database for the shop data and if it's outdated to update it and display a polaris banner that's dismissable if there's an error with the GraphQL or the database queries.
Simple when you know what you're doing. LOL
const [dismissed, setDismissed] = useState(false);
...{!dismissed && <Banner onDismiss={() => setDdismissed(true);} ....>}
– xadm