2

I am trying to get my photo blog/phlog manager component functional. However the console says the there an undefined object through props.

import React, { Component } from 'react';
import axios from 'axios';
import DropzoneComponent from 'react-dropzone-component';

import "../../../node_modules/react-dropzone-component/styles/filepicker.css";
import "../../../node_modules/dropzone/dist/min/dropzone.min.css";

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

        this.state = {
            id: '',
            phlog_status: '',
            phlog_image: '',
            editMode: false,
            position: '',
            apiUrl: 'http://127.0.0.1:8000/phlogapi/phlog/',
            apiAction: 'post'
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.componentConfig = this.componentConfig.bind(this);
        this.djsConfig = this.djsConfig.bind(this);
        this.handlePhlogImageDrop = this.handlePhlogImageDrop.bind(this);
        this.deleteImage = this.deleteImage.bind(this);

        this.phlogImageRef = React.createRef();
    }

    deleteImage(event) {
        event.preventDefault();
        axios
            .delete(
                `http://127.0.0.1:8000/phlogapi/phlog/${this.props.id}/delete`,
                { withCredentials: true }
            )
            .then(response => {
                this.props.handlePhlogImageDelete();
            })
            .catch(error => {
                console.log('deleteImage failed', error)
        });
    }

The error is occuring at Object.keys(this.props.phlogToEdit).length>0

    componentDidUpdate() {
        if (Object.keys(this.props.phlogToEdit).length > 0) {
            // debugger;
            const {
                id,
                phlog_image,
                phlog_status,
                position
            } = this.props.phlogToEdit;

            this.props.clearPhlogsToEdit();

            this.setState({
                id: id,
                phlog_image: phlog_image || '',
                phlog_status: phlog_status || '',
                position: position || '',
                editMode: true,
                apiUrl: `http://127.0.0.1:8000/phlogapi/phlog/${this.props.id}/update`,
                apiAction: 'patch'
            });
        } 
    }

    handlePhlogImageDrop() {
        return {
            addedfile: file => this.setState({ phlog_image_url: file })
        };
    }


    componentConfig() {
        return {
          iconFiletypes: [".jpg", ".png"],
          showFiletypeIcon: true,
          postUrl: "https://httpbin.org/post"
        };
    }

    djsConfig() {
        return {
          addRemoveLinks: true,
          maxFiles: 3
        };
    }

    buildForm() {
        let formData = new FormData();

        formData.append('phlog[phlog_status]', this.state.phlog_status);

        if (this.state.phlog_image) {
            formData.append(
                'phlog[phlog_image]',
                this.state.phlog_image
            );
        }

        return formData;
    }

    handleChange(event) {
        this.setState({
          [event.target.name]: event.target.value
        });
    }

    handleSubmit(event) {
        axios({
            method: this.state.apiAction,
            url: this.state.apiUrl,
            data: this.buildForm(),
            withCredentials: true
        })
        .then(response => {
            if (this.state.phlog_image) {
                this.phlogImageRef.current.dropzone.removeAllFiles();
            }

            this.setState({
                phlog_status: '',
                phlog_image: ''
            });

            if (this.props.editMode) {
                this.props.handleFormSubmission(response.data);
            } else {
                this.props.handleSuccessfulFormSubmission(response.data);
            }
        })
        .catch(error => {
            console.log('handleSubmit for phlog error', error);
        });

     event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit} className='phlog-editor-wrapper'>
                <div className='one-column'>
                    <div className='image-uploaders'>
                        {this.props.editMode && this.props.phlog_image_url ? (
                            <div className='phlog-manager'>
                                <img src={this.props.phlog.phlog_image_url} />

                            <div className='remove-image-link'>
                                <a onClick={() => this.deleteImage('phlog_image')}>
                                    Remove Photos
                                </a>
                            </div>
                        </div>
                    ) : (
                       <DropzoneComponent
                            ref={this.phlogImageRef}
                            config={this.componentConfig()}
                            djsConfig={this.djsConfig()}
                            eventHandlers={this.handlePhlogImageDrop()}
                        >
                            <div className='phlog-msg'>Phlog Photo</div>
                        </DropzoneComponent>
                    )}
                </div>
                    <button className='btn' type='submit'>Save</button>
                </div>
            </form>
        );
    }
}

export default PhlogEditor;

I do not understand how the object is empty when the props are coming from the parent component phlog-manager.js:

    import React, { Component } from "react";
import axios from "axios";

import PhlogEditor from '../phlog/phlog-editor';

export default class PhlogManager extends Component {
    constructor() {
        super();

Here I define phlogToEdit as an object to pass as props to phlogEditor child component

        this.state = {
            phlogItems: [],
            phlogToEdit: {}
        };

        this.handleNewPhlogSubmission = this.handleNewPhlogSubmission.bind(this);
        this.handleEditPhlogSubmission = this.handleEditPhlogSubmission.bind(this);
        this.handlePhlogSubmissionError = this.handlePhlogSubmissionError.bind(this);
        this.handleDeleteClick = this.handleDeleteClick.bind(this);
        this.handleEditClick = this.handleEditClick.bind(this);
        this.clearPhlogToEdit = this.clearPhlogToEdit.bind(this);
    }

    clearPhlogToEdit() {
        this.setState({
            phlogToEdit: {}
        });
    }

    handleEditClick(phlogItem) {
        this.setState({
            phlogToEdit: phlogItem
        });
    }

    handleDeleteClick(id) {
        axios
            .delete(
                `http://127.0.0.1:8000/phlogapi/phlog/${id}`,
                { withCredentials: true }
            )
            .then(response => {
                this.setState({
                    phlogItems: this.state.phlogItems.filter(item => {
                        return item.id !== id;
                    })
                });

                return response.data;
            })
            .catch(error => {
                console.log('handleDeleteClick error', error);
        });
    }

    handleEditPhlogSubmission() {
        this.getPhlogItems();
    }

    handleNewPhlogSubmission(phlogItem) {
        this.setState({
            phlogItems: [phlogItem].concat(this.state.phlogItems)
        });
    }

    handlePhlogSubmissionError(error) {
        console.log('handlePhlogSubmissionError', error);
    }

    getPhlogItems() {
        axios
          .get('http://127.0.0.1:8000/phlogapi/phlog',
            {
               withCredentials: true 
            }
          )
          .then(response => {
              this.setState({
                  phlogItems: [...response.data]
              });
          })
          .catch(error => {
              console.log('getPhlogItems error', error);
          });
    }

    componentDidMount() {
        this.getPhlogItems();
    }

    render() {
        return (
            <div className='phlog-manager'>
                <div className='centered-column'>

This is where the object, phlogToEdit is being passed as props to child component mentioned

                    <PhlogEditor
                        handleNewPhlogSubmission={this.handleNewPhlogSubmission}
                        handleEditPhlogSubmission={this.handleEditPhlogSubmission}
                        handlePhlogSubmissionError={this.handleEditPhlogSubmission}
                        clearPhlogToEdit={this.clearPhlogToEdit}
                        phlogToEdit={this.phlogToEdit}
                    />
                </div>
            </div>
        );
    }
}
4
  • When passing props to the <PhlogEditor/> shouldn't it be phlogToEdit={this.state.phlogToEdit}? You're passing the state value Commented Apr 19, 2020 at 22:15
  • @Jayce444 the documentation mentions that only a component can change its own state. props is how you pass that information to child component. Also, a child component should not change its own props. Commented Apr 19, 2020 at 22:30
  • ...ok I mean yes that's true but it has nothing to do with my comment. I was saying that you might have a typo. When passing the phlogToEdit prop you currently have phlogToEdit={this.phlogToEdit}. But you're passing the STATE value of the parent as a PROP to the PhlogEditor. So shouldn't it be phlogToEdit={this.state.phlogToEdit}? Commented Apr 19, 2020 at 22:33
  • @Jayce444 that was the solution. I misread your previous comment. That was the problem! Thank you! Commented Apr 19, 2020 at 22:39

1 Answer 1

1

@Jaycee444 solved the problem it was the parent component!

phlogToEdit={this.state.phlogToEdit}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.