How to set queryParams from react-router params
minhtranite opened this issue · 7 comments
...
var PageHome = require('components/PageHome');
var PageMeasurements = require('react-proxy?name=page-measurements!components/PageMeasurements');
var PageMeasurementsTab = require('react-proxy?name=page-measurements-tab!components/PageMeasurementsTab');
var PageMeasurementsAdd = require('react-proxy?name=page-measurements-add!components/PageMeasurementsAdd');
var PageNotFound = require('react-proxy?name=page-not-found!components/PageNotFound');
var routes = (
<Route name="app" path="/" handler={App}>
<DefaultRoute name="page-home" handler={PageHome}/>
<Route name="page-measurements" path="measurements" handler={PageMeasurements}>
<Route name="page-measurements-tab" path=":category/:type" handler={PageMeasurementsTab}>
<Route name="page-measurements-add" path="add" handler={PageMeasurementsAdd}/>
</Route>
</Route>
<NotFoundRoute name="not-found" handler={PageNotFound}/>
</Route>
);
Router.run(routes, Router.HistoryLocation, function (Handler, state) {
React.render(<Handler data="xxx" queryParams={state.params}/>, document.body);
});
With 'PageMeasurementsTab' (Transmit component) I can't get data, queryParams prod.
With 'PageHome' (normal React component) I can get data, queryParams prod
In my case, with url 'measurements/:category/:type' i want 'Transmit' get data from '/api/measurements?category=:category&type=:type' instead of '/api/measurements'.
I try change queryParams in 'componentWillMount' :
componentWillMount: function() {
this.props.setQueryParams({
category: this.context.router.getCurrentParams().category,
type: this.context.router.getCurrentParams().type
});
},
How does the resolved Handler component look like? I'd definitely use this.context.router
too but I'll need to see the Handler component to tell you how more specifically.
PageMeasurementsTab.js:
var React = require('react');
var {Link, RouteHandler} = require('react-router');
var Transmit = require('react-transmit');
var MeasurementsService = require('services/MeasurementsService');
var _ =require('underscore');
var ImageViewer = require('components/ImageViewer');
var PageMeasurementsTab = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
componentWillMount: function() {
this.props.setQueryParams({
category: this.context.router.getCurrentParams().category,
type: this.context.router.getCurrentParams().type
});
},
renderMeasurements: function(){
return _.map(this.props.measurements, function(measurement){
return (
<tr key={measurement.id}>
<td><ImageViewer data-src={measurement.image} width="100" height="80"/></td>
<td>{measurement.title}</td>
<td>{measurement.instruction}</td>
<td>{measurement.video}</td>
<td>{measurement.created_at}</td>
<td>{measurement.id}</td>
<td></td>
</tr>
);
});
},
render: function() {
var category = this.context.router.getCurrentParams().category;
var type = this.context.router.getCurrentParams().type;
return (
<div>
<section className="action-bar">
<Link className="btn btn-primary" to="page-measurements-add" params={{category: category, type: type}}>
<i className="glyphicon glyphicon-plus"></i> Add new measurement
</Link>
<form className="action-bar-search-form form-inline pull-right">
<div className="form-group">
<div className="input-group">
<input type="text" className="form-control"
placeholder="Search measurement"></input>
<span className="input-group-btn">
<button className="btn btn-default" type="button">
<i className="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
</form>
</section>
<table className="table table-bordered">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Instruction</th>
<th>Video</th>
<th>Created</th>
<th>ID</th>
<th>Options</th>
</tr>
<tbody>
{this.renderMeasurements()}
</tbody>
</thead>
</table>
<RouteHandler/>
</div>
);
}
});
module.exports = Transmit.createContainer(PageMeasurementsTab, {
queries: {
measurements: function(queryParams){
return MeasurementsService.query(queryParams).then(function(response){
return response.body;
});
}
}
});
MeasurementsService.js:
var Config = require('config');
var Request = require('superagent');
var prefix = require('superagent-prefix')(Config.apiPrefix);
var Promise = require('promise');
var MeasurementsService = {
query: function(params){
var queries = params || {};
return new Promise(function(resolve, reject){
Request.get('/api/measurements')
.use(prefix)
.query(queries)
.end(function(error, response){
if(error){
reject(error);
}
resolve(response);
});
});
}
};
module.exports = MeasurementsService;
Hmmmm.... In the first solution, the one that doesn't use context:
Transmit.createContainer(PageMeasurementsTab, {
queries: {
measurements: function(queryParams){
/**!!!! .... queryParams should contain the {state.params} here !!!**/
return MeasurementsService.query(queryParams).then(function(response){
return response.body;
});
}
}
});
@vn38minhtran Did you have the time to verify the above? I'll leave this issue open for a bit longer.
Thanks for help! I will close issue and try your solution laster.
@RickWong actually your solution doesn't work for me.
Transmit.createContainer(PageMeasurementsTab, {
queries: {
measurements: function(queryParams){
/**!!!! .... queryParams should contain the {state.params} here !!!**/
return MeasurementsService.query(queryParams).then(function(response){
return response.body;
});
}
}
});
queryParams
doesnt' contain state.params
. Container resets passed props. Isn't this a typo?
componentWillMount: function() {
var externalQueryParams = this.props && this.props.queryParams || {}; // shoudn't it be || instead of && ?
this.currentParams = assign({}, Container.queryParams, externalQueryParams);
if (!this.hasQueryResults()) {
this.setQueryParams({});
} else if (this.props.onQuery) {
this.props.onQuery.call(this, Promise.resolve({}));
}
},
My bad, was a bug in my code.