Search code examples
meteorreactjsmeteor-react

Calling Meteor methods in React components


Currently I'm working on a project based on Meteor as back end and React as front end. I really enjoyed simplicity untill I removed insecure package and have to deal with Meteor methods. Right now I need to perform a basic insert operation and I'm just stucked! I have a form as component (in case eventually I'd like to use this form not only for inserting items but for editing those items as well) and here's my code for this form:

AddItemForm = React.createClass({
propTypes: {
    submitAction: React.PropTypes.func.isRequired
 },
getDefaultProps() {
    return {
        submitButtonLabel: "Add Item"
    };
},
render() {
    return (
        <div className="row">
            <form onSubmit={this.submitAction} className="col s12">
                <div className="row">
                    <div className="input-field col s6">
                        <input  
                            id="name"
                            placeholder="What" 
                            type="text" 
                        />
                    </div>
                    <div className="input-field col s6">
                        <input 
                            placeholder="Amount" 
                            id="amount" 
                            type="text" 
                         />
                    </div>
                </div>
                <div className="row">
                    <div className="input-field col s12">
                        <textarea 
                            placeholder="Description" 
                            id="description"
                            className="materialize-textarea">
                        </textarea>
                    </div>
                    </div>
                    <div className="row center">
                        <button className="btn waves-effect waves-light" type="submit">{this.props.submitButtonLabel}</button>
                    </div>
                </form>
            </div>
        );
    }
});

This chunk of code is used as a form component, I have a prop submitAction which I use in let's say add view:

AddItem = React.createClass({
handleSubmit(event) {
    event.preventDefault();
    const 
        name = $('#name').val(),
        amount = $('#amount').val(),
        description = $('#description').val();
        Items.insert(
            {
                name: name,
                range: range,
                description: description,
                createdAt: new Date(),
                ownerId: Meteor.userId()
            },
            function(error) {
                if (error) {
                    console.log("error");
                } else {
                    FlowRouter.go('items');
                };
            }
        );
    },

    render() {
        return (
            <div className="row">
                <h1 className="center">Add Item</h1>
                    <AddItemForm
                        submitButtonLabel="Add Event"
                        submitAction={this.handleSubmit}
                    />
            </div>
        );
    }
}); 

As you can see I directly grab values by IDs then perform insert operation which works absolutely correct, I can even get this data displayed. So now I have to remove insecure package and rebuild the whole operation stack using methods, where I actually stucked. As I understand all I should do is to grab same data and after that perform Meteor.call, but I don't know how to pass this data correctly into current method call. I tried considering this data right in the method's body which doesn't work (I used the same const set as in AddItem view). Correct me if I'm wrong, but I don't think this method knows something about where I took the data (or may be I don't really get Meteor's method workflow), so by this moment I ended up with this code as my insert method:

Meteor.methods({
    addItem() {
        Items.insert({
            name: name,
            amount: amount,
            description: description,
            createdAt: new Date(),
            ownerId: Meteor.userId()
        });
    }
});

and this is how I changed my handleSubmit function:

handleSubmit(event) {
    event.preventDefault();
    const 
        name = $('#name').val(),
        amount = $('#amount').val(),
        description = $('#description').val();
    Meteor.call('addItem');
},

Also I tried declaring method like this:

'addItem': function() {
    Items.insert({
        // same code
    });
}

but it also didn't work for me. Again, as I understand the problem isn't about data itself, as I wrote before it works just right with insecure package, the problem is how the heck should I get this data on the server first and right after that pass this to the client using methods (also console gives no even warnings and right after I submit the form, the page reloads)? I've already seen some tutorials and articles in the web and didn't find desicion, hope to get help here.


Solution

  • You can add your data as parameters in your Meteor call function. You can also add a callback function to check on the success of the call.

    handleSubmit(event) {
      event.preventDefault();
      const 
        name = $('#name').val(),
        amount = $('#amount').val(),
        description = $('#description').val();
      Meteor.call('addItem', name, amount, description, function(err, res) {
        if (err){
          console.log(JSON.stringify(err,null,2))
        }else{
          console.log(res, "success!")     
        }
      });
    },
    

    In your Meteor methods:

    Meteor.methods({
      addItem(name, amount, description) {
    
        var Added =  Items.insert({
          name: name,
          amount: amount,
          description: description,
          createdAt: new Date(),
          ownerId: Meteor.userId()
        });
    
        return Added
    
      }
    });