How can I prevent a Shopify Polaris React app from connecting to Shopify service too soon?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How can I prevent a Shopify Polaris React app from connecting to Shopify service too soon?



I'm new to react and I'm trying to build a basic Shopify app using React and the Polaris React suite.



TL:DR;



How can I prevent a React component from rendering until data has been fetched asynchronously from the server? OR What is the correct method to get a Polaris app to connect to the shopify service?



Full Explanation



The problem is the render function should add the store domain to an attribute on the <AppProvider/> element. Ie. <AppProvider shopOrigin="https://user-store.myshopify.com"/> However, the domain differs depending on the store using the app.


<AppProvider/>


<AppProvider shopOrigin="https://user-store.myshopify.com"/>



Given that React is rendered on the client side, I need to send a request to the server to retrieve the current store domain. But this happens after the app has rendered:


render() {

return (
<AppProvider
shopOrigin=this.state.shop /* Null when first rendered */
debug=true
> ... </AppProvider>



This results in the Polaris app atempting to connect to Shopify with a Null value for the shop domain and everything breaks.


Null



I've been able to prevent this by having the render function return Null on the first render but this feels kind of hacky


Null


render() {

if (typeof this.state.shop === 'undefined') /* true on first render */
return null; /* prevent rendering at this stage */

return (
<AppProvider
shopOrigin=this.state.shop
debug=true
>



Here is the async function that I'm using to get the domain from the server


constructor()
super();

this.state = ;


componentDidMount()
this.callApi()
.then(res => this.setState(res))
.catch(err => console.log(err));


callApi = async () =>
const response = await fetch('/shopify/config');
const body = await response.json();

if (response.status !== 200) throw Error(body.message);

return body;
;





Makes no sense that you are waiting around till you can ask for the domain from the server? When would you ever have a Shopify call hit your App without the name of the shop in the payload? All Shopify EASDK setups provide you with the shop. Your use case or how you are using EASDK seem odd. For kicks can you explain briefly what you are trying to do with Polaris?
– David Lazar
Aug 12 at 3:24





@DavidLazar After studying your comment, i looked again at the way I'm doing things. After a POST request to 'https://' + domain + '/admin/oauth/access_token'; I do a res.redirect('/') which means i loose the store domain. For that reason I store it in the session. Hence the need for a request to the server to retrieve it. I think I need to get rid of the redirect and serve the app from the &redirect_uri=https://$appDomain/shopify/auth location
– andrew
Aug 12 at 6:57



'https://' + domain + '/admin/oauth/access_token';


res.redirect('/')


&redirect_uri=https://$appDomain/shopify/auth





The idea is to use your session. When you get an oAuth token you persist it along with the store myshopify.com domain name. That way when a merchant clicks into your App, you match the supplied shop name to your DB and get the existing token, setup a session and carry on.
– David Lazar
Aug 12 at 19:51




1 Answer
1



A simple way to do this is keeping an 'isLoading' attribute in your component's state, which is initially set to true.


'isLoading'


true



Once your component has finished fetching whatever data it needs to, call this.setState(isLoading: false).


this.setState(isLoading: false)



Then your component's render method should look something like this:


render()
const isLoading = this.state;

if (isLoading)
return <span>loading...</span>


return <AppProvider ...props/>



This way your app won't try to connect to the Shopify service until it is done fetching data.



Of course you can make the return value of render whatever you like, maybe put a loading icon/animation in there, or just return an empty <div>.


render


<div>





Oh this is a fantastic Idea, and it gives the user feedback during the async request that something is happening! Thanks
– andrew
Aug 12 at 2:13





@andrew Of course. It's a nice little trick for any time a component needs to fetch and display data so your app looks good even while fetching.
– Henry Woody
Aug 12 at 2:15






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard