2

This is my first attempt at using Relay Modern. Fetching for a specific User from a PostgraphQL GraphQL Server. It is fetching the data successfully but not passing to render function:

import {createFragmentContainer, QueryRenderer, graphql} from 'react-relay'
import environment from 'environment'

@CSSModules(styles) export default class Profile extends Component {   
  render() {
    var {props: {children}} = this
    return (
      <QueryRenderer
        environment={environment}
        query={graphql`
          query ProfileQuery {
            userById(id: "f0301eaf-55ad-46db-ac90-b52d6138489e") {
              firstName
              userName
            }
          }
        `}
        render={({error, relayProps}) => {
          if (error) {
            return <div>{error.message}</div>
          } else if (relayProps) {
            ...
          }
          return <div>Loading...</div>
        }}
      />
    )   
  }
} 

Only "Loading..." is rendered.

I am guessing because it successfully fetches data that the graphql server and environment are ok.

I am not using React 16 and the project also uses Redux.

Any suggestions please as to why relayProps wouldn't have a value (e.g. relayProps.user)?

One further thing that may help, the environment (file) is in the main application and the QueryRenderer and components are in an imported npm package (to be shared across a number of applications). As mentioned, the query seems to work fine so I did not think this was a problem. I also run the relay compiler on the package but not the main application since there are no relay components there.

Just in case it's needed the environment is setup using:

const {
  Environment,
  Network,
  RecordSource,
  Store,
} = require('relay-runtime')

// Instantiate Store for Cached Data
const store = new Store(new RecordSource())

// Create Network for GraphQL Server
const network = Network.create((operation, variables) => {
  // GraphQL Endpoint
  return fetch(config.gqlapiProtocol + "://" + config.gqlapiHost + config.gqlapiUri + "/a3/graphql" , {
    method: 'POST',
    headers: {
      'Content-Type': "application/json",
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: operation.text,
      variables,
    }),
  }).then(response => {
    return response.json()
  })
})

// Instantiate Environment
const environment = new Environment({
  network,
  store,
})

// Export environment
export default environment
Abdullah
  • 2,015
  • 2
  • 20
  • 29
Ashley Aitken
  • 2,419
  • 2
  • 20
  • 24
  • Are you sure your network layer is being called?. Do you see your data and/or errors in the response.json(). In my case I have a subsequent `.then(json => { // Allow Relay onError to get fired in case of errors in response // See: https://github.com/facebook/relay/issues/1816 // NOTICE: that data might contain values even when errors present if(json.errors && json.errors.length > 0) { return Promise.reject(json); } return Promise.resolve(json); })` – hisa_py Oct 16 '17 at 12:59
  • Yes, I see the correct data in the response. This is why I felt confident network was ok. No error in call to render either. Thank you for your comments. I will try your suggestion though, nice addition. – Ashley Aitken Oct 16 '17 at 16:22

1 Answers1

1

props are not relayprops

    render={({ error, props }) => {
      if (error) {
        return <div>{error.message}</div>;
      } else if (props) {
        ...
      }
      return <div>Loading...</div>;
    }}

and

fetch(GRAPHQL_URL, {
  method: 'POST',
  get headers() {
    return {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    };
  },
  body: JSON.stringify({
    query: operation.text, // GraphQL text from input
    variables
  })
})
  .then(response => response.json())
  .then((json) => {
    // https://github.com/facebook/relay/issues/1816
    if (operation.query.operation === 'mutation' && json.errors) {
      return Promise.reject(json);
    }

    return Promise.resolve(json);
  })
);
Ng Thong
  • 104
  • 1
  • 6
  • Thank you but I am not sure the name of the parameter (props, relayProps, x, y, z, ...) makes any difference in this case? I think the code is just defining a function that takes a deconstructed object with two attributes and uses those attributes within the function. Please correct me if I am wrong. – Ashley Aitken Oct 25 '17 at 17:10
  • 1
    `render={({ error, props, retry }) => { }}` or `render={(relayProps) => { const { error, props, retry } = relayProps; }}` do you understand it? – Ng Thong Oct 26 '17 at 02:18
  • Not sure why this got downvoted. The name matters if you are trying to destructure the parameter, he's right. – bplittle Sep 10 '20 at 04:25
  • it makes no difference, it's just ES6 Destructuring assignment syntax – Ng Thong Sep 22 '20 at 06:30