I am trying to add a spinner loading component which the app is in loading state

juleshaydn
New Member
4 0 0

This still returns the following error for me. (ReferenceError: isTheAppLoading is not defined)

 

import App from "next/app";
import Head from "next/head";
import { AppProvider } from "@shopify/polaris";
import { Provider, Loading } from "@shopify/app-bridge-react";
import translations from "@shopify/polaris/locales/en.json";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";

const client = new ApolloClient({
  fetchOptions: {
    credentials: "include",
  },
});

class MyApp extends App {
  isTheAppLoading() {
    return true;
  }
  render() {
    const { Component, pageProps } = this.props;
    const loading = isTheAppLoading();
    const loadingComponent = loading ? <Loading /> : null;
    return (
      <React.Fragment>
        <Head>
          <title>Sample App</title>
          <meta charSet="utf-8" />
        </Head>
        <Provider
          config={{
            apiKey: API_KEY,
            shopOrigin: shopOrigin,
            forceRedirect: true,
          }}
        >
          {loadingComponent}
          <AppProvider i18n={translations}>
            <ApolloProvider client={client}>
              <Component {...pageProps} />
            </ApolloProvider>
          </AppProvider>
        </Provider>
      </React.Fragment>
    );
  }
}

export default MyApp;
0 Likes
andrew-apperley
Shopify Staff
Shopify Staff
20 5 4

Hey @juleshaydn ,

I see this is in response to a similar question that was answered already.

The missing piece with your code is the lack of `this` being used when accessing the `isTheAppLoading` function of your class. When accessing member functions or variables of a class or even a plain old object for that matter you need to reference them with the `this` keyword or else Javascript will attempt to find the the function/variable within the global scope, which then fails like in your case.

 

You can see this if you have linting, ESLint in my case, enabled in an IDE where it warns you that the function name `isTheAppLoading` is not found. I've included a screenshot to demonstrate this. I hope that helps.

Screen Shot 2021-02-25 at 3.23.58 PM.png

Andrew Apperley
(App Bridge) Mobile Developer
juleshaydn
New Member
4 0 0

Thanks for the reply, I am using the (this) keyword and it still gives me the loading indicator after the page has loading, how can I get this to indicate during the loading process?

 

class MyApp extends App {
  isTheAppLoading() {
    return true;
  }
  render() {
    const { Component, pageProps, shopOrigin } = this.props;
    const loading = this.isTheAppLoading();
    const loadingComponent = loading ? <Loading /> : null;
    const config = {
      apiKey: API_KEY,
      shopOrigin: shopOrigin,
      forceRedirect: true,
    };
    const client = new ApolloClient({
      fetch: fetch,
      fetchOptions: {
        credentials: "include",
      },
    });

    return (
      <AppProvider i18n={translations}>
        <Provider config={config}>
          <ApolloProvider client={client}>
            {loadingComponent}
            <Component {...pageProps} />
          </ApolloProvider>
        </Provider>
      </AppProvider>
    );
  }
}

MyApp.getInitialProps = async ({ ctx }) => {
  return {
    shopOrigin: ctx.query.shop,
  };
};

export default MyApp;
0 Likes
andrew-apperley
Shopify Staff
Shopify Staff
20 5 4

The reason the loading indicator is still present is because you're always setting it to true inside your isTheAppLoading function. You need to make that return value from the function be based off of other state in your application. For instance if another value being present inside the Application State is only present after the app is loaded then you could return that.

isTheAppLoading() {
    return this.state.SOMEVALUE === null; // it being null indicates the app is still loading
 }

 

Let me know if that helps you out. 

Andrew Apperley
(App Bridge) Mobile Developer
0 Likes