[RESOLVED] Passing variables to a template nested in a react component


#1

I’ve got a react component that wraps a blaze template, inspiration from here: https://gist.github.com/emdagon/944472f39b58875045b6

I want to do this because I want to use react, but still want to use blaze packages like easy search in my react component like this:

someComponent = React.createClass({
render() {
    return <div>
        <span>Hello {this.data.currentUser.profile.name}!</span>
        <IncludeTemplate template={Template.esInput} data='{"index":"organisations"}' />
    </div>;
}
});

The IncludeTemplate looks much like the link above with one difference, I’m parsing the data field as json to pass into the template being rendered (because easy search requires a index to be specified and passed into the template):

var IncludeTemplate = React.createClass({
    componentDidMount: function() {
        var componentRoot = React.findDOMNode(this);
        var parentNode = componentRoot.parentNode;
        parentNode.removeChild(componentRoot);
        return Blaze.renderWithData(this.props.template, JSON.parse(this.props.data), parentNode);
    }, //<-- here, I'm creating the template and passing in data, manual json parsing
    render: function(template) {
        return (<div />)
    }
});

My question is, I feel it’s a bit of a hack to pass in the data field as a string and then have to json.parse it. Is there a simpler way?


React + React Router + Templates?
Useraccounts with react?
Preview of official React support
#2

Answering my own question, I just created my own props convention like this (btp === Blaze Template Parameter):

<BlazeTemplate template={Template.esInput} btp-index='organisations' btp-test='hi' />

and then use it like this:

var BlazeTemplate = React.createClass({
    componentDidMount: function() {
        var componentRoot = React.findDOMNode(this);
        var parentNode = componentRoot.parentNode;
        parentNode.removeChild(componentRoot);
        var data = {};
        _.each(this.props, function (val, key) {
            if (key.lastIndexOf('btp-', 0) === 0)
                data[key.slice(4)] = val;
        });
        return Blaze.renderWithData(this.props.template, data, parentNode);
    },
    render: function(template) {
        return (<div />)
    }
});

Now I should be able to include any blaze atmosphere templates within a react component :smile:


#3

@mordrax, I am using your component above to render a custom autoform that inserts a document.

<template name="insertCustomDealForm">
  {{#autoForm collection="Deals" id="insertCustomDealForm" type="insert"}}
      {{> afQuickField name='dealName'}}
    <button type="submit" class="ui button">Insert</button>
  {{/autoForm}}
</template>

Here I include it in my component:

<div className="sixteen wide column">
          <div className="ui segments">
            <div className="ui secondary segment">
              <p>Top</p>
            </div>
            <div className="ui segment">
              <BlazeTemplate template={Template.insertCustomDealForm} />
            </div>
          </div>
        </div>

This is working alright, however, is it possible somehow to have the onSubmit event fire off when I click the submit button? I want to reroute the page to a view of the newly created document. I can do this no problem with a form I create directly in my render(), but not able to throw back the onSubmit event when I call the <BlazeTemplate template={Template.insertCustomDealForm} />

Any thoughts?


#4

Looks like you’re looking for autoforms hooks?

Just put a after insert hook on your form and it should trigger after your onSubmit returns (note, this isn’t after your server call’s come back, if you want that, then you’re looking for the onSuccess hook.