Amber passing model to transition ToRoute
I am using Ember-cli since ember 1.11
I am trying to use the transitionToRoute method in a controller to navigate to a route and feed it with a dynamically generated object as a model.
Here's my controller:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
launch_scanner: function(){
console.log('launch_scanner');
var model = {name: "Edward", phone: "123", email: "email@test.com"};
//the final app will pull the model variable from a QR scanner
this.transitionToRoute('addcontact', model);
}
}
});
When I run this activity, the transitionToRoute method throws this error:
Search error: More context objects passed than there are dynamic segments for route: addcontact
If I don't specify a model parameter, it just goes to the addcontact route. What am I doing wrong?
Here is my router file:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('home', {path: '/'});
this.resource('addcontact', {path: '/addcontact'});
});
export default Router;
source to share
You are dealing with a classic problem found in many Ember applications, which allows you to handle "new" / "create" situations.
You cannot define a route like
this.route('addcontact', { path: /addcontact/:thing_id }
because the new contact does not have an ID and will not be until it is saved on the server, after which it will not be new.
However, there is some point in your application, in your case, I suppose, on the home page where the user clicked the "New Contact" button and it might have useful information on what to create or how to create one. and might even want to create an object right there using this.store.createRecord
- but how to pass this information or a new entry onto a route addcontacdt
that dynamic segment cannot have?
Some ideas include:
-
Create a new contact in your route
home
or whatever and save it to your controller. Then, in themodel
hook of the new route, extract it withthis.controllerFor('home').get('newContact')
. -
Pass the required parameters to create the new object, if any, into the route
addcontact
as query parameters usingtransitionTo('newcontact', queryParameters)
. Then, in themodel
hook, create a new object usingthis.store.createRecord('contact', transition.queryParameters)
or something equivalent.
This is fine because you don't have a dynamic segment in your addContact route. You must change your router to
Router.map(function() {
this.route('home', {path: '/'});
this.resource('addcontact', {path: '/addcontact/:id'});
});
You can now pass the model id instead of the whole model to call the hook model
. Alternatively, you can pass the entire model, but it won't trigger the hook model
. Although you can change your model to afterModel
.
source to share
If you want to jump to the subroutine for the unsaved entry, you have 2 options
Or save the model before going to the route
model.save().then(function(result){
self.transitionToRoute('route',result.id)
});
or create an id for the model in createRecord if you don't want to save the model (maybe the user can cancel and you don't want to handle deletion)
The main function for creating low potential ids of identical ids would be:
generateIdForRecord: function() {
var d = new Date().getTime();
var uuid = 'xxxxyyyxxxxxxxxyyxyxxxyyy'.replace(/[xy]/g, function(c){
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
}
Using this approach, the not yet saved model has an id to navigate, just think about handling transitions from that route as the current id is no longer valid after the model is saved (the model gets the real id from the server in return).
source to share