madsmosu
madsmosu

Reputation: 1

Graphql query result comes back undefined

I am getting the error Uncaught (in promise) TypeError: Cannot read property 'privateKey' of undefined

Employee query result comes back undefined when trying to console.log this.props.employee

I am using Graphql and Next.js. Am unsure whether or not componentWillMount is the correct lifecyle method to use as this.props.data.employee is undefined.

    class EmployeeTable extends Component {
    state = {
        employeesList: [],
        privateKey: ""
    }

    fetchEmployees = async () => {
        console.log(this.props.data.employee);
        console.log(this.props.data.employee.privateKey);
        const adminWallet = new ethers.Wallet(this.state.privateKey, provider);
        const EmployeeStore = new ethers.Contract(address, abi, adminWallet);

        let count;
        await EmployeeStore.functions.employeesCount().then(function(value) {
        count = value;
        });

        let employeesList = [];
        for(let i = 1; i<=count; i++) {
            await EmployeeStore.getEmployeeByIndex(i).then(function(result) {
            employeesList.push(result);
        });
        };
        console.log(employeesList);
        return {employeesList}; 
    };


    componentWillMount = async () => {
        var employees = await this.fetchEmployees();
        this.setState({employeesList: employees});
    };  

    renderRows() {
        return this.state.employeesList.map((employee, index) => {
            return (<EmployeeRow
                key={index}
                employee={employee}
            />
            );
        });
    };

    render() {
        const { Header, Row, HeaderCell, Body } = Table;
        return(
            <div>
                <h3>Employees</h3>
                <Table>
                    <Header>
                        <Row>
                        <HeaderCell>Name</HeaderCell>
                        <HeaderCell>Employee ID</HeaderCell>
                        <HeaderCell>Address</HeaderCell>
                        <HeaderCell>Authenticated</HeaderCell>
                        </Row>
                    </Header>
                    <Body>{this.renderRows()}</Body>
                </Table>
            </div>
        )
    }
}

const employee = gql`
query employee($employeeID: String){ 
    employee(employeeID: $employeeID) {
        privateKey
    }
}
`;

export default graphql(employee, {
    options: {
        variables: {employeeID: "1234"}
    },
  })
  (EmployeeTable);

Upvotes: 0

Views: 1342

Answers (1)

Tal Z
Tal Z

Reputation: 3210

The first time a component wrapped with a Query operation, like in your code, is rendered it receives the data prop but without the results yet.

data contains a field called loading. If it is set to true, it means the query didn't receive all the results from the server yet. If the operation is successful, next time your component is rendered this.props.data will have loading === false and this.props.data.employee should be have a value as you expect.

Basically, you should check if this.props.data.loading is true or false before calling fetchEmployees() and before rendering child components that rely on the results.

Upvotes: 0

Related Questions