Using this.transitionTo to change query params gives error - javascript

Using pretty much copy paste from Ember.js docs
App.CresShowResultController = Ember.ArrayController.extend({
queryParams: ['county'],
county: null,
actions: {
displayQueryData: function(){
this.transitionTo({queryParams: {county: 'someCounty'}});
},
},
});
The action is called from another controller after a form is analysed.
I get an error: Uncaught TypeError: undefined is not a function
Here is the route as well.
App.CresShowResultRoute = Ember.Route.extend({
renderTemplate: function(){
this.render('showResult');
}
});
SideQuestion: How can I use transitionTo to change URL parameters straight from another controller without using the action "displayUseryData" as middleman function?
EDIT: Added my Router.map to specify:
App.Router.map(function(){
this.resource('cres', function() {
this.route('showResult');
});
this.resource('about');
this.resource('posts', function() {
//child route posted inside the parent
this.resource('post', { path: ':post_id'});
});
});
Like always, thank you for any helping comments!

try:
App.CresShowResultController = Ember.ArrayController.extend({
queryParams: ['county'],
county: null,
actions: {
displayQueryData: function(){
this.transitionTo({queryParams: {county: 'someCounty'}});
}.bind(this),
},
});
I think that "this" in the displayQueryData function is a window reference.

In the case you reference above, just updating the queryParam itself will have the effect you are looking for.
In the route, you can define if these queryParams will replace the url, or if it will refresh the model.
Use the transitionToRoute, when you wish to switch to a different route, or different model.
App.CresShowResultController = Ember.ArrayController.extend({
queryParams: ['county'],
county: null,
actions: {
displayQueryData: function(){
this.set('county', 'someCounty');
// this.transitionTo({queryParams: {county: 'someCounty'}});
},
},
});

Related

backbone fragment route is added to root when has :attributes

I'm quite new using Backbone and now I have found this new issue.
I use the route "jobprofile" to create a view which fetch the data from urlRoot= "job" (doing job/id using a default id) BUT if I add the :id to the route as "jobprofile/:id" which I need to type in the browser to be able to get the job.id view, then it stops to work and the url of the model change to: ".../jobprofile/job/id" which (obviously) give me 404 error.
Hope is clear. Thanks!
CODE:
I have a router.js
routes: {
...
"jobprofile/:id": "view", //without /:id works!
},
view:function(id){
console.log("view");
this.job = new Job();
this.job.setId(id); //This is set correctly
this.jobProfileView = new JobProfileView({
model: this.job,
el: $('.tab-content')
});
},
(View)JobProfileView.js:
...
initialize: function(){
var that = this;
this.model.fetch().done(function(){
console.log("fetch done!");
that.render();
});
},
...
(Model)Job.js:
urlRoot: 'job',
initialize: function () {
},
setId: function (job_id) {
this.set('id', job_id);
},
UPDATED:
Ok. So it looks that I "fix" the problem adding this.navigate('/jobprofile'); to the method view in router.js. I guess that the /:id which causes the problem is deleted from the route (actually when you see the browser its not there anymore) but I still keep the id in the method.
In any case, this is a really bad solution because when I try to go back it creates a bucle and it goes to jobprofile/id and navigate again to jobprofile. So if anyone has an idea it would be great...
Finally I understood what the problem was...
Basically there is a difference when in the url or urlRoot are set in the model. Thus, these two options appear:
url:'/foo'. In this case it will not take the base url.
example: www.web.com/foo
url:'foo'. In this case, it will take the base url
example: www.web.com/api/foo
My case is as follow:
(Model)Job.js:
urlRoot: '/job',
initialize: function () {
},
setId: function (job_id) {
this.set('id', job_id);
},

How to get the type of route path in Ember

If I have in the router map:
this.resource('detail', { path: '/detail/:type' }, function() {
...
});
And I retrive the currentPanth in my Ember Application code:
currentPath: '',
ApplicationController : Ember.Controller.extend({
updateCurrentPath: function() {
App.set('currentPath', this.get('currentPath'));
console.log('currentPath',App.currentPath);
}.observes('currentPath')
}),
When I navigate in my app, I get the route names by console, but when It is "detail" I get "detail.index". How can I get the type?
you only have access to the params in the route, ie. when you are defining your model:
App.Router.map(function() {
this.resource('photo', { path: '/photos/:photo_id' });
});
App.PhotoRoute = Ember.Route.extend({
model: function(params) {
return Ember.$.getJSON('/photos/'+params.photo_id);
}
});
Or you can also use paramsFor, also in the route only.
Depending on what you are trying to acomplish maybe query params suit better

How do I call a controller action from an Ember route while doing a transition?

My objective is to display a fancy "loading..." graphic on my page while Ember fetches model data through the Ember route.
This led me to http://emberjs.com/guides/routing/loading-and-error-substates/. That inspired me to create an action on my page's controller which would show the "loading" overlay window in the DOM. For example, here's my controller:
controllers/users.js:
export default Ember.ArrayController.extend({
...
actions: {
displayLoading: function() {
// Show the DOM element that says "Loading..."
},
...
}
});
I'd like to call that while my data is loading, so I then define a route as follows:
routes/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function(transition, originRoute) {
transition.send('displayLoading');
}
}
});
But when I do this, I get this error:
Uncaught Error: Nothing handled the action 'displayLoading'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.
So my question is where can I define this action so that my loading method will be able to call it?
Note that trying this.send('displayLoading') gave me this error:
Can't trigger action 'displayLoading' because your app hasn't finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call .send() on the Transition object passed to the model/beforeModel/afterModel hooks..
Update: I am able to catch this action on the route itself, but then I still can't call the action on my controller.
Update #2: Thanks to #kingpin2k's answer, I've resolved this. For those interested, here is a full solution:
controllers/users.js:
export default Ember.ArrayController.extend( {
actions: {
showLoading: function() {
this.set('isLoading', true);
},
hideLoading: function() {
this.set('isLoading', false);
},
}
});
routers/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function() {
this.controllerFor('users').send('showLoading');
},
didTransition: function() {
this.controllerFor('users').send('hideLoading');
}
}
});
A key insight was that I can set an isLoading property on my controller which determines whether my modal "Loading..." window is showing in the Handlebars template.
use controllerFor, http://emberjs.com/api/classes/Ember.Route.html#method_controllerFor
loading: function(transition, originRoute) {
var controller = this.controllerFor('foo');
controller.send('displayLoading');
}

Model reloading with Ember Data

I'm trying to poll for more data using the documented model.reload() function
App.ModelViewRoute = Ember.Route.extend({
actions: {
reload: function() {
this.get('model').reload();
}
}
});
But i'm getting an error message saying...
undefined is not a function TypeError: undefined is not a function
Is there a better way of doing this, it seems like I cannot access the model in this way from the route?
Here is the router
App.Router.map(function() {
this.route('video', { path: '/videos/:video_id' });
});
Here is the route
App.VideoRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('video', params.video_id);
},
actions: {
reloadModel: function() {
// PROBLEM HERE
// this.get('model').reload();
Ember.Logger.log('reload called!');
}
}
});
Here is the model
App.Video = DS.Model.extend({
title: DS.attr('string'),
status: DS.attr('string')
});
And the templates
<script type="text/x-handlebars" data-template-name="application">
<h1>Testing model reloading</h1>
{{#link-to "video" 1}}view problem{{/link-to}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="video">
<h1>Video</h1>
<h2>{{title}}</h2>
{{model.status}}
<p><button {{action 'reloadModel'}}>Reload model</button></p>
</script>
I've made a jsbin of the issue here:
http://jsbin.com/wofaj/13/edit?html,js,output
I really can't understand why the reload gives me this error. Any advice would be much appreciated.
Thanks
Since model already exists as a hook on Ember.Route, you cannot get that as a property.
Instead you can do the following:
this.modelFor('video').reload();
Technically you could do this.get('currentModel').reload(); too, but that's undocumented and probably won't be available in the future.
The refresh method of the route would do what you're after
App.VideoRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('video', params.video_id);
},
actions: {
reloadModel: function() {
this.refresh()
}
}
});
API docs
The route model function provides a hook to load your controller data. There is a specific section at the ember guide.
1) If you want to access your content, it would be like:
reload: function() {
this.controller.get('content');
}
2) reload is a method available of ember-data objects. In your example, you are loading a js object ({ id:2, title:"Test video title 2", status:"downloading"}).

Meteor JS: Conditional subscriptions, based on passed arguments, in Iron Router?

This is really two questions:
Is it possible to conditionally subscribe to collections within Iron Router's waitOn option?
Is it possible to pass in objects as an argument in Router.go()?
I am trying to reduce the delay in rendering a view, when creating a new post within my app. I tried passing in an isNew property as an argument for Router.go(), but had no luck:
// Router call after creating a new post
Router.go('postPage', {
_id: id,
isNew: true,
post: newPostObject
});
// router.js
Router.map(function() {
this.route('postsList', {
path: '/'
});
this.route('postPage', {
path: '/:_id',
waitOn: function() {
//This returns only _id for some reason.
console.log(this.params);
if (this.params.isNew != true) {
return [
Meteor.subscribe('singlePost', this.params._id),
Meteor.subscribe('images', this.params._id),
]
}
},
data: function() {
if (this.params.isNew == true) {
return this.params.post
else {
return Posts.findOne(this.params._id);
}
}
});
});
After some digging, it looks likes Iron Router supports an options hash as a third argument in the Router.go() method:
Router.go( 'postPage', {_id: id}, {isNew: true} );
To access it in the route, you can use then use this.options. To get the value of isNew in the above example, use this.options.isNew.
you can only access Dynamic Path Segments by this.params. so to get this.params.isNew working you need to have it like this.
this.route('postPage', {
path: '/:_id/:isNew',
waitOn: function() {}
...
});

Categories

Resources