We have a form to create a new account report on account.reports.new, and when we save it should transition to the account.reports.report route as below:
route
saveReport(report) {
report.set('isNewReport', false);
report.save()
.then(() => this.transitionTo('account.reports.report', report.get('id')))
.catch(e => console.log(e));
},
This is all well and good, but I'd rather not pass report.get('id') in and have it make an API request in the model() hook (since we already have the saved model right there). So I try to pass the model in directly, like... this.transitionTo('account.reports.report', report)... and Ember gets very unhappy:
ember.debug.js:28573 Error while processing route: account.reports.report You must provide param `reportId` to `generate`. Error: You must provide param `reportId` to `generate`.
at getParam (http://localhost:4200/assets/vendor.js:65828:11)
at DynamicSegment.generate (http://localhost:4200/assets/vendor.js:65887:17)
at RouteRecognizer.generate (http://localhost:4200/assets/vendor.js:66238:25)
at updateURL (http://localhost:4200/assets/vendor.js:68349:33)
at finalizeTransition (http://localhost:4200/assets/vendor.js:68403:5)
at http://localhost:4200/assets/vendor.js:67797:12
at tryCatch (http://localhost:4200/assets/vendor.js:69106:14)
at invokeCallback (http://localhost:4200/assets/vendor.js:69121:15)
at publish (http://localhost:4200/assets/vendor.js:69089:9)
at http://localhost:4200/assets/vendor.js:48993:16
Same issue happens if I do this via a controller with transitionToRoute('account.reports.report', report). It loads the account.reports.report template and has the model, but it stays on the account.reports.new route.
Routes are set up as..
this.route('account', function() {
this.route('reports', function() {
this.route('new');
this.route('report', { path: '/:reportId' });
});
});
Twiddle here:
https://ember-twiddle.com/04f934f126d31aa5c4a3e8831c01c0ad?openFiles=templates.things.new.hbs%2C&route=%2Fthings%2Fnew
@kevlarr , The issue is not with your approach, but how you set path for your route in the router that matters. _This should not be an issue with ember at all_.
You have configured your report route path as this.route('report', { path: '/:reportId' });.
So when you pass the model objectreport, the router tries to resolve the property reportId from your model object(report) which is not present. Only report.id is present.
So what you have to do is configure the path as this.route('report', { path: '/:id' }); and the router will resolve the id property from the passed model object report and makes a smooth transition to reports/${report.id}.
In this case model() hook of the reports.report route will not be invoked, since you are passing the entire model object. Hope this satisfies your need!
For your twiddle if we follow ember convention then it should go like this this.route('thing', { path: ':thing_id' });. if you replace this then your twiddle will work as expected.
Closing this since @SharavanaPrasad and @kumkanillam had given the right solution for this.
Thank you all!
@Serabe Just saw the responses.. My question is, can this explicitly be stated in the docs somewhere? "Convention" isn't a good word for something that is mandatory.
@SharavanaPrasad @kumkanillam That's perfect, thanks for the help!! We hadn't seen anywhere that using :id was actually necessary.
@kevlarr it is written in the _Dynamic Segments_ section of the guides
Ember follows the convention of
:model-name_idfor two reasons. The first reason is that Routes know how to fetch the right model by default, if you follow the convention. The second is thatparamsis an object, and can only have one value associated with a key.
Thank you!
Routes know how to fetch the right model by default, if you follow the convention
That doesn't have anything to do with _providing_ a model, hence the confusion.
Thanks for pointing that out though, I appreciate that you went to find the resource. I'll drop it, I get the reasons for it now.
Most helpful comment
@kevlarr it is written in the _Dynamic Segments_ section of the guides
Thank you!