Ember js params not passing properly - ember.js

I have the routes defined in following way
this.route('league', {path: '/league'}, function () {
this.route('matches', {path: '/'});
this.route('create-team', {path: '/:matchId'}, function () {
this.route('team',{path: '/team'});
});
});
And i am trying to load all the players associated with a matchId inside team router as following
import Route from '#ember/routing/route';
export default Route.extend({
model: function(params) {
return this.store.query('player', {'match': params.matchId});
}
});
The problem is that the params is empty. I tried to pass in hard values to the json query and it worked with get request but it doesn't work like this. Where am i going wrong with this ?

In your child route, you can call paramsFor and fetch the parameters (including query parameters) for a named route.
In your case, I believe you'll call
let params = this.paramsFor('league.create-team')
let match = params.matchId;

Related

Ember.Js Using TransitionTo Route with dynamic segment

I have an ember application (version 3.14) which I'd like to do a transition to a Route with dynamic segment
I'd like to redirect to /projects/other/2020 when user visits /projects/other
I change my projects/other route so it looks like this but it throws me an error
import Route from '#ember/routing/route';
export default Route.extend({
model: function(){
},
redirect() {
let year_data = {
year: '2020'
};
this.transitionTo('projects.other',year_data);
}
});
and this is how my projects route looks like in routes.js
this.route('projects', function() {
this.route('notable',{path: '/'});
this.route('other', function() {
this.route('list', {path: '/:year'});
});
});
these are the errors from google chrome console box
error screenshot
Error message is pretty clear. You are trying to redirect to projects.other.index route which does not have any dynamic segments. Also, according to docs, you need to pass an id and not an object. When you pass an object, ember treats it like ready to use model. So, your code should be
this.transitionTo('projects.other.list', '2020');

Ember nested global routes (Wildcard)

I'm trying to do something like this in my routes:
this.route('products', { path: "/products/*choises"}, function() {
this.route('promotion', {path: "/promotion/*offers"});
});
product route:
offerPath: function(params){
this.transitionTo('product.promotion', params);
}
The problem is that it doesn't matter the promotion that I visit, the app thinks is part of the products route.
How can I do this? I need them to be nested.
Update:
You can use beforeModel(transition) hook in router to check what's in the url.
http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel(transition) {
console.log(transition.params.products.choises)
// if you use this url: http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless
// console log would be: "manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless"
}
});
At least you have the rest of the url so, you can filter out the important information and redirect with this.transitionTo() to the exact place.
You could have the following route:
http://example.com/products/123/promotions/456
or
http://example.com/products/awesome_souce/promotions/monday_deal
In the first case, your route would look like this:
this.route('product', { path: "/products/:product_id"}, function() {
this.route('promotion', {path: "/promotions/:promotion_id"});
});
In the second case, maybe like this:
this.route('product', { path: "/products/:product_name"}, function() {
this.route('promotion', {path: "/promotions/:promotion_name"});
});
Finally, your route handlers can download the proper models (example for the first case):
// app/routes/product.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('product', params.product_id);
}
});
---
// app/routes/product/promotion.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
// you can get access to the parent route model if you need for the api query
const product = this.modelFor('product');
return this.store.findRecord('promotion', params.promotion_id);
}
});
If you need only the param from the product route, instead of returning a whole record, for example you can just return params.product_name, so you will have access to a string with this.modelFor('product') in a subroute level.

How can I transitionTo a route that includes a model id, from having the id stored in a variable?

Here is my router.js:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('category', {path: '/category/:category_id'});
this.route('listing', {path: '/listing/:listing_id'});
});
export default Router;
I'm trying to make it so that when the user selects an option from the navbar component, they will be redirected to the appropriate categories/category_id page. I am able to get the right ID into a variable in the navbar component but my this.transitionTo statement does not work. Here is the navbar-header.js:
import Ember from 'ember';
export default Ember.Component.extend({
model() {
return this.store.findAll('category');
},
actions: {
categorySelected: function(){
debugger;
var e = document.getElementById("categories");
var catId = e.options[e.selectedIndex].value;
//I have verified that catId contains the appropriate ID at this point.
//Where the error happens:
this.transitionTo('/category/' + catId);
}
}
});
What am I doing wrong?
EDIT: Heads up everyone, you can't do a transitionTo from a component, you have to use an action and send it back to the route. And as joshfarrent said it is supposed to be this.transitionTo('category', catId);
You need to pass the Id as a separate param in the transitionTo, and remove the slashes, like this:
this.transitionTo('category', catId);
See the transitionTo section of the Ember Route docs here.
I'd also recommend against using the HTML element's value to figure out which item has been selected, and rather do something like this on each action helper in your template:
{{action "categorySelected" VALUE}}
Just replace VALUE with the same numerical value that you were setting on the HTML element. This way, the value of the element will be passed to your categorySelected function as follows:
categorySelected: function(value) {
debugger;
this.transitionTo('category', value);
}
Finally, is there a reason you're not just using a {{link-to}} helper to achieve the same effect?

EmberJS get dynamic parameter in nested route

I am developing a website using Ember JS.
I have created a nested route like this:
//router
this.resource('store/checkout', {path: '/store/checkout/:order_id'}, function(){
this.resource('store/checkout-lines', {path: ''});
});
This results in the route /store/checkout/:order_id calling both routes and corresponding tempaltes.
The template for store/checkout has an {{outlet}} for the template store/checkout-lines.
In the routes I have this code:
//store/chekout
export default Ember.Route.extend({
model: function(params) {
return this.store.find('order', params.order_id);
}
});
//store/checkout-lines
export default Ember.Route.extend({
model: function(params) {
var order_id = params.order_id; //this does not work
return this.store.find('order-item', {orderId: order_id});
}
});
But my problem is that in the route for store/checkout-lines, I cannot get the orderId.
How can I achieve this? Or am I at the wrong track and should be doing this in another way?
My goal is that the route /store/checkout/:order_id should call the server to fetch both order and orderItems.
What some people seem to miss is that even if you are visiting a nested route, the model for the parent route is loaded. In your nested route, you can easily fetch the model from the parent route using modelFor(type)and then get your information from there. In your case it would be like this.
//store/checkout-lines
export default Ember.Route.extend({
model: function(params) {
var order_id = this.modelFor('checkout').get('id');
return this.store.find('order-item', { orderId: order_id });
}
});
This might seem like an extra step but when you get around to it it really makes a lot of sense and works very well.

Ember v1.6.0beta is removing the query string from the URL - Cannot get queryParam

Ember seems to be removing the query string from the URL.
I've stepped through the code, and I know for sure that I'm setting the flag correctly:
<script>
ENV = {FEATURES: {'query-params-new': true}};
</script>
<script src="js/libs/ember.prod-1.6.0beta+canary.js"></script>
But when my route loads, the query string is being removed, and I can't access the queryParams.
Here's my router:
App.Router.map(function () {
this.resource('simpleSearch', {path: 'simplesearch'}, function () {
this.resource('simpleSearchOption', {path: ':simpleSearchOption_id'});
this.resource('simpleSearchResults', {path: 'results'});
});
});
When I attempt the following url (which is based on the URL from the guide), the query string is stripped: [webserver]/#/simplesearch/0?simplesearch[height]=10
When the model is first initialized by the route, it builds out what the query parameters will be, and the controller's queryParams property is set by the route:
App.SimpleSearchRoute = Ember.Route.extend({
model: function () {
var optionsForSimpleSearchModel = [];
for (var i = 0; i < App.SimpleSearchOptions.length; i++) {
optionsForSimpleSearchModel[i] = App.SimpleSearchOption.create(App.SimpleSearchOptions[i]);
}
return App.SimpleSearch.create({
'simpleSearchOptions': optionsForSimpleSearchModel,
'numOfOptions': App.SimpleSearchOptions.length
});
},
setupController: function (controller, model) {
console.log(model.get('queryParams'));
controller.set('queryParams', model.get('queryParams'));
controller.set('model', model);
}
});
BUT, I've also tried explicitly setting the queryParams in the controller:
App.SimpleSearchController = Ember.ObjectController.extend({
height: null,
queryParams: ['height'],
...
I'm not sure what else I'm missing...
How does this thing really work?
It seems that I'm a silly dude.
I needed to add the params argument to the model() function:
model: function (params) {
console.log(params);
//{height: null} when queryParams['height'] is explicitly set in the controller
Is there any way that I can dynamically generate the queryParams for the controller before Ember decides there are none, if I don't set them explicitly?
Also, my URL was incorrect, (as is the one in the Ember guide). It should have been:
[webserver]/#/simplesearch/0?height=10
instead of
[webserver]/#/simplesearch/0?simplesearch[height]=10
In your model hook you need to pass in the params.
App.SimpleSearchRoute = Ember.Route.extend({
model: function (params) {
return this.store.findQuery('simpleSearch', params);
}
});
Here is another question along the same lines.
Cheers