[SOLVED] Form submitting with Meteor and React


#1

Hello good people.
Another day another trouble. I have two collections: let’s say Items and Reviews, items get created by an admin and anyone can leave a review (without logging in). I have an issue with form submitting for reviews. I’ll try to keep the following code as clear as possible explaining how it works now and how it supossed to work. Let’s start.
First things first, I have a component for a single item with form where a person can write a review (every single item has a form):

import React, {Component, PropTypes} from 'react';
import ReviewForm from './ReviewForm.jsx';

import {Items} from '../../api/collections/items.js';
import {Reviews} from '../../api/collections/reviews.js';


export default class Item extends Component {
    render() {
        return (
            <div className="container">
                <div className="row">
                    <p>{this.props.item.itemName}</p>
                </div>
    		<div className="row"
                    <p>{this.props.item.itemDesc}</p>
		</div>
            </div>
            <div className="row">
                <form onSubmit={this.props.leaveData}>
                    <div className="row">
                        <div className="input-field col s6">
                             <input placeholder="Name" id="review_body" type="text" />
                        </div>
                    </div>
                    	<button type="submit">Send Review</button>
                    </div>
                </form>
             </div>
        )
    }
}

Item.propTypes = {
    item PropTypes.object.isRequired,
    leaveData: PropTypes.func.isRequired,
};

As you can see nothing very special (proptypes for items work perfect though), I have a leaveData function which I use to reach this component in ItemsList component:
import React, { Component, PropTypes } from ‘react’;
import { createContainer } from ‘meteor/react-meteor-data’;
import Item from ‘./Item.jsx’;
import {Items} from ‘…/…/api/collections/items.js’;
import {Reviews} from ‘…/…/api/collections/reviews.js’;

class ItemssList extends Component {
    handleSubmit(event) {
        event.preventDefault();
        
        const reviewBody = $('#review_body').val();
        
        Reviews.insert({
            reviewBody, 
            createdAt: new Date(),
        });
    }
    renderItems() {
        return this.props.items.map((item) => (
            <Item key={item._id} item={item} leaveData={this.handleSubmit} />
        ));
    }
    render() {
        return (
            <div className="row">
                {this.renderItems()}
            </div>
        )
    }
}

ItemsList.propTypes = {
    items: PropTypes.array.isRequired,
}

export default createContainer(() => {
    return {
        items: Items.find({}).fetch(),
    };
}, ItemsList);

So the code is pretty straightforward and I use almost the same code to create a new item on admin page, the only difference is that admin page has only one form, but I want every item object to have a reviewing form. May be I messed up with ID’s but not sure about it. Right now it works okay but only when I submit a review for the very first item, for further items this form submits an empty document and I just don’t know what can be a reason for such behavior. Hope to hear any suggestions to help me get through this at first sight trivial task!

`


#2

Well guys I think I almost got it. See why exactly every single item object shows correctly? 'Cause every this ibject has an unique ID which I specified in renderItems function. I will try to do the same for a form component later and keep you posted about this solution.


#3

Here you’re asking jquery to get your review body input value by id (#review_body). You have multiple inputs on the same page with this exact same id, so jquery is likely grabbing the first one every time (id’s should be unique). I’d suggest getting the review body value from the submitted form by extracting it out of handleSubmit's passed in event object.


#4

Did you notice that spelling error?


#5

Thanks for replying guys, I really appreciate this!

@newswim yes you’re right, I misspelled class’ name but only in my post, the code doesn’t contain this error.

@hwillson you’re right too, with some help I realized that I only had to use refs instead of grabbing IDs, so it was the issue