访问查询返回对象的ID字段会将其更改为未定义

时间:2018-12-03 03:39:10

标签: reactjs mongodb mongoose graphql apollo

我正在使用react / mondgodb / graphql / apollo网络应用程序。我有一个查询来设置使用fbid的成员(它是我以fbid插入的firebase ID,以便通过firebase id在我的数据库中找到已登录的成员概要文件)。当我执行查询时,我可以console.log整个查询返回的数据。如果尝试访问数据成员,则会得到该对象未定义的信息。这是我查询的组件:

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom'
import { graphql, compose } from 'react-apollo';
import { withFirebase } from '../Firebase';
import { getMemberByFBidQuery } from '../../queries/queries';

import DataList from '../wishes/MyDataList';

const INITIAL_STATE = {
    memberProfile: {},
    error: null
}

class DashboardGuts extends Component {
    constructor(props) {
        super(props);

        this.state = { ...INITIAL_STATE };
    }

    render() {
        const memberProfile = this.props.getMemberByFBidQuery.memberByFBid;
        console.log('memberProfile: ', memberProfile.id);

        return (
            <div className="dashboard container">
                <div className="row">
                    <div className="col s12 m6">
                        <h4>My Data List</h4>
                        <DataList memberProfile={memberProfile} />
                    </div>
                </div>
            </div>
        )
    }
}

const Dashboard = withFirebase(DashboardGuts)

export default compose(
    graphql(getMemberByFBidQuery, {
        name: "getMemberByFBidQuery",
        options: (props) => {
            return {
                variables: {
                    fbid: props.firebase.auth.O
                }
            }
        }
    }),
)(Dashboard)

当我在上面的代码中console.log memberProfile时,我得到了期望从查询中返回的所有数据。 console.log输出如下所示:

memberProfile:  
    {firstname: "jo", lastname: "blo", id: "1234", 
     fbid: "5678", __typename: "Member"}
     fbid: "5678"
     firstname: "jo"
     id: "1234"
     lastname: "smith"
     __typename: "Member"
     __proto__: Object
 }

问题是当我尝试访问memberProfile对象内的任何字段时-像id一样,出现错误。例如,如果我更改此行:

console.log('memberProfile: ', memberProfile);

对此:

console.log('memberProfile: ', memberProfile.id);

然后我得到一个错误,我无法访问未定义对象的ID。 enter image description here

关于如何访问该id属性的任何想法?如果有帮助,这里是实际的graphQL查询:

const getMemberByFBidQuery = gql`
query($fbid: String){
    memberByFBid(fbid: $fbid) {
        firstname,
        lastname,
        id,
        fbid
    }
}

`

这是该查询的架构:

memberByFBid: {
        type: MemberType,
        args: { fbid: { type: GraphQLString } },
        resolve(parent, args) {
            return Member.findOne({ fbid: args.fbid });
        }
    },

这是MemberType的架构:

const MemberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
    id: { type: GraphQLID },
    firstname: { type: GraphQLString },
    lastname: { type: GraphQLString },
    email: { type: GraphQLString },
    fbid: { type: GraphQLString },
    wishes: {
        type: GraphQLList(WishType),
        resolve(parent, args) {
            return Wish.find({ memberId: parent.id })
        }
    },
    groups: {
        type: GraphQLList(MemberToGroupMapType),
        resolve(parent, args) {
            return MemberToGroupMap.find({ memberId: parent.id });
        }
    }
})
});

在此先感谢您的帮助!

根据TLadd的建议,我更改了渲染功能,但是我仍然遇到错误。她目前是:

render() {
    console.log('look for loading: ', this.props);
    const { memberByFBid, loading, error } = this.props.getMemberByFBidQuery;

    if (loading) {
        return (<p>Loading...</p>);
    } else if (error) {
        return (<p>Error!</p>);
    }

    console.log('memberProfilexx: ', memberByFBid);

    return (
        <div className="dashboard container">
            <div className="row">
                <div className="col s12 m6">
                    <h4>My Wish List</h4>
                    <WishList memberProfile={memberByFBid} />
                </div>
                <div className="col s12 m5 offset-m1">
                    <div>Hello</div>
                </div>
            </div>
        </div>
    )
}

但是如果我尝试console.log memberByFBid.id而不是仅memberByFBid,仍然会收到错误消息。

1 个答案:

答案 0 :(得分:0)

您遇到此错误是因为DashboardGuts组件首次尝试呈现时查询尚未加载。从数据属性的react-apollo docs(在本例中为getMemberByFBidQuery,因为您在graphql HOC中指定了自定义名称配置选项):

  

请确保在渲染之前始终检查组件中的data.loading和data.error。当组件执行其初始提取操作时,包含您应用程序数据的data.todos之类的属性可能未定义。检查data.loading和data.error可以帮助您避免未定义数据的任何问题。

遵循此建议,您的渲染方法将变得类似

render() {
  const { memberByFBid, loading, error } = this.props.getMemberByFBidQuery;

  if (loading) {
    return <p>Loading...</p>;
  } else if (error) {
    return <p>Error!</p>;
  }

  console.log('memberProfile: ', memberProfile.id);
  return (
    <div className="dashboard container">
      <div className="row">
        <div className="col s12 m6">
          <h4>My Data List</h4>
          <DataList memberProfile={memberProfile} />
        </div>
      </div>
    </div>
  )
}

您可能希望以一种更具吸引力的方式处理加载/错误状态,但是主要思想是您需要考虑render方法中尚未加载的数据,因为它不会出现在初始位置。渲染。