1
votes

I'm trying to pass props candidate_information from my parent component to my child component. So far I'm able to pass it although I'm running into an issue with "cannot read property 'id' of undefined'. Property id does exist and candidate_information is defined. Although when I console.log(this.props.candidate_information) in my child render, it logs undefined first and then the given data with property id while this.props.candidate_inforation.id is undefined. Why is that and how can I fix this issue? Ultimately I want to be abled to use this.props.candidate_information.id in my child's ternary statement.

PARENT CODE

class Stage1Page extends Component {
    handleChange = (candidate) => {
    this.setState({
        showProfile: true,
        spotlightCandidate: candidate,
    });
    this.retrieveCandidateInfo(candidate);
};
// retrieves candidate info
retrieveCandidateInfo = (candidate) => {
    const access_token = JSON.parse(localStorage['appState']).user
        .access_token;

    // Hard code token for the time being
    const config = {
        headers: {
            Authorization: 'Bearer ' + access_token,
        },
    };

    axios
        .get(
            'https://reactreactexample.com/api/v1/candidate/' +
                candidate.id,
            config
        )

        .then((response) => {
            // handle success
            console.log(response.data);
            this.setState({ candidate_information: response.data });
        })
        .catch((error) => {
            if (error.response) {
                // The request was made and the server responded with a status code
                // that falls out of the range of 2xx
                alert('error');
                console.log(error.response.data);
                console.log(error.response.status);
                console.log(error.response.headers);
            } else if (error.request) {
                // The request was made but no response was received
                // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
                // http.ClientRequest in node.js
                console.log(error.request);
            } else {
                // Something happened in setting up the request that triggered an Error
                console.log('Error', error.message);
            }
            console.log(error.config);
        });
};


    render() {

    return (
        <div className='candidates-page'>
            <CreateCandidate
                onClose={this.showCreate}
                show={this.state.show}
            />
            <CandidateProfile
                onClose={this.showCandidateProfile}
                show={this.state.showProfile}
                spotlightCandidate={this.state.spotlightCandidate}
                candidate_information={this.state.candidate_information}
            />
            <SearchBar handleSearch={this.searchUpdate} />
            <Header />
            <div className='candidate-list-container'>
                    <DataTable
                        theme='solarized'
                        customStyles={customStyles}
                        noHeader={true}
                        fixedHeader={true}
                        columns={columns}
                        data={dataTable}
                        onRowClicked={this.handleChange}
                        pagination={true}
                        responsive={true}
                    />
                </div>
       </div>
     )}

CHILD CODE

render() {
    if (!this.props.show) {
        return null;
    }

    console.log(this.props.candidate_information.id);

    return (
        <div className='candidate-profile'>
            <div className='directory'>
                <div className='background' />
                <div className='box'>

                    {this.props.candidate_information === undefined ? (
                        <div>SUCCESS</div>
                    ) : (
                        <div>FAIL</div>
                    )}
                </div>
            </div>
       </div>
)}
1
Please candidate_informaiton format. - Sandy
candidate_information = {id: 286, name: "NAme", current_company_name: "Company", job_title: "Title", email: "[email protected]", …} - Michael Lee
I don't see state being initialized with candidate_information property. - Sandy
I initialized candidate_information in my GET request with this.setState({ candidate_information: response.data }) and then passed the data using props. - Michael Lee
@MichaelLee, try to initialize your candidate_information to a [] default first and see if you have that problem. Another thing, is the child component being called from some other component and you're not passing candidate_information down to it? - Shohin

1 Answers

2
votes

It's because the first time your component renders candidate_information isn't set because the async query has not returned:

   .then((response) => {
        // handle success
        console.log(response.data);
        this.setState({ candidate_information: response.data });
    })

2 Solutions:

First, don't render your child until the candidate_information is set. To do this, check to see if the parent has passed it. If it is undefined, your HTTP request must not have returned yet so it's not time to show the component.

render() {
if (this.props.candidate_information === undefined || !this.props.show) {
    return null;
}

Second, you can do this in the parent (set show to false if the request has not returned your candidate information yet):

   <CandidateProfile
            onClose={this.showCandidateProfile}
            show={this.state.showProfile && this.state.candidate_information}
            spotlightCandidate={this.state.spotlightCandidate}
            candidate_information={this.state.candidate_information}
        />