简体   繁体   中英

React + Apollo: GraphQL errors array not passed into component

According to these Apollo docs , setting an error-policy of all should make the errors array of a GraphQL response available to my Apollo-wrapped React component "so [my] UI can use them." My app is universal, so it's important I use this policy so an error doesn't prevent the app from rendering entirely.

The trouble is, even though my browser dev tools show the errors array in the server response, I can't ever access it in my React component's props. Similarly, props.data.error is always undefined. Why is this?

// Component
import React from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

const Cart = (props) => {
  console.log(props.errors); // undefined
  console.log(props.data.error); // undefined
  console.log(props.data.cart); // null

  return <div>Foo.</div>;
};

export default graphql(gql`
  query CartQuery {
    cart {
      products {
        _id,
        name
      }
    }
  }
`, { options: { errorPolicy: 'all' } })(Cart);


// Resolver
cart: (root, args, context) => {
  throw new Error('foo');
}


// Browser network tab response
{"data":{"cart":null},"errors":[{"message":"foo","locations":[{"line":2,"column":3}],"path":["cart"]}]}

undefined means there is no error so you successfully fetched the data you are having issue displaying the component on the screen because fetching data from graphQL server is an async operation. if you

       console.log(props)

you will see 2 data objects in the console. In the first one, data.loading:true

that means fetching is in progress and there is no return yet. So when you render your component your component will not have anything to display.

if you check the second data object you will see

data.loading:false

and that means fetching is resolved and if it is successfully resolved you will see

data.QueryCart: "response will be here"

if promise was rejected you would have data.error was populated with the error message

so what you should do is implementing a conditional rendering. while

if(props.data.loading){
        return (
            <div>Loading</div>
        )
    }
return <div>Foo.</div>

once the props.data.loading changes to false render return <div>Foo.</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM