Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Docs link display continuous loading image when clicked #212

Closed
vikram9r opened this issue Nov 15, 2016 · 15 comments
Closed

The Docs link display continuous loading image when clicked #212

vikram9r opened this issue Nov 15, 2016 · 15 comments
Labels

Comments

@vikram9r
Copy link

vikram9r commented Nov 15, 2016

I have implemented GraphQL server using java, the sever is able to listen and respond to the the query requests but when i first request the GraphiQL in browser the the introspection response json was being displayed in the GraphiQL response window and when I click the Docs link I see the continuous loading image.

The other graphql requests which I send from the GraphiQL request editor are working fine and I can even see the response back displaying in the GraphiQL response window

Note
I am using https://github.com/graphql/graphiql/blob/master/example/index.html in my application resources to load the GraphiQl from my server.

@vikram9r vikram9r changed the title The Docs link disply continous loading image when clicked The Docs link display continuous loading image when clicked Nov 15, 2016
@vikram9r
Copy link
Author

graphiql

@asiandrummer
Copy link
Contributor

Hi @vikram9r - Doc Explorer shows a loading spinner when there is no schema passed in/defined by the fetcher function. Is there a code snippet I can take a look to help you further?

@vikram9r
Copy link
Author

vikram9r commented Nov 16, 2016

This is the java resource which would accept the graphql query as a string

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/graphql")
    public JsonNode  getResponse(@RequestBody Map<String, String> body) {
        String response = bssApiWrapper.getGraphOf(body.get("query"));

        JsonNode node = null;
        try{
        node = new ObjectMapper().readValue(response, JsonNode.class);
        }catch(Exception e){
            e.printStackTrace();
        }
        return node;
    }

@vikram9r
Copy link
Author

Hi @asiandrummer can you suggest me on about how the GraphQL server implementation should be?
can you provide some example template code of GraphQL server which would describe how it should receive the request and respond back.

could you please check above code and help me

Thank you!

@asiandrummer
Copy link
Contributor

@vikram9r - it's hard to help with the code you provided unfortunately; how are you mounting GraphiQL? You'd need to pass in a fetcher function to further execute the queries with. Could you show me how you're creating the web page with GraphiQL in it?

@vikram9r
Copy link
Author

Hi @asiandrummer - thank you for the response !
I am using the following code in my server application to render the html of graphiql and you can find a fetch function in it which would request the /graphql url path

<!--
 *  Copyright (c) 2015, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the license found in the
 *  LICENSE file in the root directory of this source tree.
 *
-->
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        height: 100%;
        margin: 0;
        width: 100%;
        overflow: hidden;
      }
      #graphiql {
        height: 100vh;
      }
    </style>

    <!--
      This GraphiQL example depends on Promise and fetch, which are available in
      modern browsers, but can be "polyfilled" for older browsers.
      GraphiQL itself depends on React DOM.
      If you do not want to rely on a CDN, you can host these files locally or
      include them directly in your favored resource bunder.
    -->
    <script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
    <script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
    <script src="//cdn.jsdelivr.net/react/15.3.2/react.min.js"></script>
    <script src="//cdn.jsdelivr.net/react/15.3.2/react-dom.min.js"></script>

    <!--
      These two files can be found in the npm module, however you may wish to
      copy them directly into your environment, or perhaps include them in your
      favored resource bundler.
     -->
    <link rel="stylesheet" href="/assets/css/graphiql.css" />
    <script src="/assets/js/graphiql.js"></script>

  </head>
  <body>
    <div id="graphiql">Loading...</div>
    <script>
      /**
       * This GraphiQL example illustrates how to use some of GraphiQL's props
       * in order to enable reading and updating the URL parameters, making
       * link sharing of queries a little bit easier.
       *
       * This is only one example of this kind of feature, GraphiQL exposes
       * various React params to enable interesting integrations.
       */
      // Parse the search string to get url parameters.
      var search = window.location.search;
      var parameters = {};
      search.substr(1).split('&').forEach(function (entry) {
        var eq = entry.indexOf('=');
        if (eq >= 0) {
          parameters[decodeURIComponent(entry.slice(0, eq))] =
            decodeURIComponent(entry.slice(eq + 1));
        }
      });
      // if variables was provided, try to format it.
      if (parameters.variables) {
        try {
          parameters.variables =
            JSON.stringify(JSON.parse(parameters.variables), null, 2);
        } catch (e) {
          // Do nothing, we want to display the invalid JSON as a string, rather
          // than present an error.
        }
      }
      // When the query and variables string is edited, update the URL bar so
      // that it can be easily shared
      function onEditQuery(newQuery) {
        parameters.query = newQuery;
        updateURL();
      }
      function onEditVariables(newVariables) {
        parameters.variables = newVariables;
        updateURL();
      }
      function onEditOperationName(newOperationName) {
        parameters.operationName = newOperationName;
        updateURL();
      }
      function updateURL() {
        var newSearch = '?' + Object.keys(parameters).filter(function (key) {
          return Boolean(parameters[key]);
        }).map(function (key) {
          return encodeURIComponent(key) + '=' +
            encodeURIComponent(parameters[key]);
        }).join('&');
        history.replaceState(null, null, newSearch);
      }
      // Defines a GraphQL fetcher using the fetch API. You're not required to
      // use fetch, and could instead implement graphQLFetcher however you like,
      // as long as it returns a Promise or Observable.
      function graphQLFetcher(graphQLParams) {
        // This example expects a GraphQL server at the path /graphql.
        // Change this to point wherever you host your GraphQL server.

        return fetch('/graphql', {
          method: 'post',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(graphQLParams),
          credentials: 'include',
        }).then(function (response) {
          return response.text();
        }).then(function (responseBody) {
          try {
            return JSON.parse(responseBody);
          } catch (error) {
            return responseBody;
          }
        });
      }
      // Render <GraphiQL /> into the body.
      // See the README in the top level of this module to learn more about
      // how you can customize GraphiQL by providing different values or
      // additional child elements.
      ReactDOM.render(
        React.createElement(GraphiQL, {
          fetcher: graphQLFetcher,
          query: parameters.query,
          variables: parameters.variables,
          operationName: parameters.operationName,
          onEditQuery: onEditQuery,
          onEditVariables: onEditVariables,
          onEditOperationName: onEditOperationName
        }),
        document.getElementById('graphiql')
      );
    </script>
  </body>
</html>

In the above code the file paths for graphiql.js and graphiql.css are the files which i have copied from node_modules folder of npm

@asiandrummer
Copy link
Contributor

Ok, the code looks ok to me as it looks mostly of the GraphiQL example code. When it's mounted for the first time, GraphiQL tries to send an introspection query to the server, and I think that's the step failing for you. I'd advise to check if the introspection query is correctly sent what the app is loaded.

FYI this snippet is how we ensure the schema is available when the component gets mounted, which is also where the introspection is done.

@vikram9r
Copy link
Author

vikram9r commented Dec 1, 2016

When it's mounted for the first time, GraphiQL is sending an introspection query to the server and the server is responding as below
graphiql

I hope this is what the response which GraphiQL introspection is expecting from server, if so what i am doing wrong

@vikram9r
Copy link
Author

vikram9r commented Dec 1, 2016

Please be noted that I am not using Node.js for server implementation rather I am using java https://github.com/bpatters/schemagen-graphql

leebyron added a commit that referenced this issue Jan 10, 2017
When introspection fails to load a schema (or a schema is intentionally excluded via providing `null` as the prop), the doc explorer currently continues to show a loading indicator. This change alters that behavior to instead declare that no schema exists. This also ensures schema is set to `null` after failure to load via introspection.

Fixes #212
@leebyron
Copy link
Contributor

Hey @vikram9r -

This state can occur in two ways:

  1. Your server is taking a very long time to fulfill the introspection query.

  2. GraphiQL fails to load the schema from your server via introspection. Typically it reports the error into the results screen when this occurs, though to be safe you could also look in the javascript error console to see if there's a deeper issue.

I've added a change which makes errors loading the schema more clear in GraphiQL doc explorer so at least you would know the difference between continuing to wait for the introspection result vs that resulting in an error.

leebyron added a commit that referenced this issue Jan 10, 2017
When introspection fails to load a schema (or a schema is intentionally excluded via providing `null` as the prop), the doc explorer currently continues to show a loading indicator. This change alters that behavior to instead declare that no schema exists. This also ensures schema is set to `null` after failure to load via introspection.

Fixes #212
@bencooling
Copy link

@vikram9r Wrapping the json response from graphql server with { data: {} } as mentioned here solved this problem for me: #185 (comment)

@leebyron
Copy link
Contributor

Ah good to know. Just curious what server implementation you're using? Queries should always have the "data" field as defined by the spec. It might be helpful to report a bug.

http://facebook.github.io/graphql/#sec-Data

@bencooling
Copy link

@leebyron I was writing my own simple implementation but I was ignorant of the spec. Thank you for your feedback.

@leebyron
Copy link
Contributor

Cool :)

@devalexua
Copy link

@bencooling Thank you! Spent a lot of time trying to figure out what was the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants