maxwellgover
maxwellgover

Reputation: 7111

Error - Firebase.push failed:

I'm trying to push a collection of questions and associated options to a firebase ref called 'quizzes'. When clicking submit I get the following in the console.

Uncaught Error: Firebase.push failed: first argument contains an invalid key ($$typeof) in property 'quizzes.questions.0'. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"

I have no idea what ($$typeof) means here or really how to solve this issue. I'm pushing Option components into a Question components array [ ] and then pushing the question component into the QuizBuilderForm array [ ].

Thanks!

Here is my code

// Quiz Builder Component

import React from 'react';
import Question from './Question';
import firebase from 'firebase';

const QuizBuilderForm = React.createClass({
    getInitialState: function() {
        return {
            questions: [],
        };
    },
    addQuestion: function(questions, index) {
        index = this.state.questions.length;
        questions = this.state.questions;
        questions.push(<Question key={index} id={index}/>);
        index++;
        this.setState({
            questions: questions
        });
    },
    componentDidMount: function() {
        this.addQuestion();
    },
    handleSubmit: function(event) {
        event.preventDefault();
        this.firebaseRef = firebase.database().ref('quizzes');
        this.firebaseRef.push({
            questions: this.state.questions
        });
        this.refs.form.reset();
        this.setState({
            questions: []
        });
    },
    render: function() {
        return (
            <form className="quiz-form" onSubmit={this.handleSubmit} ref="form">
                {this.state.questions}
                <button type="button" className="add-question" onClick={this.addQuestion}>Add a question</button>
                <button type="submit">Create Quiz</button>
            </form>      
        );
    }
});

export default QuizBuilderForm;

// Question Component 

import React from 'react';
import Option from './Option';

const Question = React.createClass({
    getInitialState: function() {
        return {
            value: "",
            options: []
        };
    },
    handleChange: function(e) {
        this.setState({
           value: e.target.value 
        });
    },
    addOption: function(options, index) {
        index = this.state.options.length;
        options = this.state.options;
        options.push(<Option key={index} id={index} />);
        index++;
        this.setState({
            options: options

        });
    },
    componentDidMount: function() {
        this.addOption();
    },
    render: function() {
        return (
            <div className="question">
                <input type="text" value={this.state.value} onChange={this.handleChange}></input>
                {this.state.options}
                <button type="button" onClick={this.addOption}>Add another option</button>
            </div>
        );
    }
});

export default Question;

// Options component 

import React from 'react';

const Option = React.createClass({
    getInitialState: function() {
        return {
            value: ""
        };
    },
    handleChange: function(e) {
        this.setState({
            value: e.target.value
        });
    },
    render: function() {
        return (
            <input type="text" value={this.state.value} placeholder="Enter an answer here" onChange={this.handleChange}></input>        
        );
    }
});

export default Option;

Upvotes: 0

Views: 581

Answers (1)

Arpit
Arpit

Reputation: 438

There are 2 major mistakes that I find in your code.

  1. You are trying to push a react component on firebase which is not going to work. You need to push an array of string or an array of objects.

  2. You are trying to set the sub-component at the state variable of the parent component. You shouldn't be doing that. You need to set the data you want to display as the state of the component and then pass this data to your sub-component and let sub-component decide how to render it.

Upvotes: 1

Related Questions