Ember nested global routes (Wildcard) - ember.js

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.

Related

Ember js params not passing properly

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;

Getting specific item with findRecord

I'm new at ember and as first app I'm trying to build a little online shop.
I can receive "all products" as product overview but not one specific product by id.
I have following in the router.js:
Router.map(function() {
this.route('products');
this.route('product', {path: 'products/:product_id'});
});
My products.js (which works):
import Ember from 'ember';
export default Ember.Route.extend({
model(){
return this.get('store').query('product', {});
}
});
And the product.js (which does generate the problem):
import Ember from 'ember';
export default Ember.Route.extend({
model(params){
return this.store.findRecord('product', params.product_id);
}
});
The project is available under https://github.com/hatchling-shop/hatchling/tree/master/EmberHatchling
After running the code seems that you have an issue in the API in Product.findById() and not in Ember.
In the following method:
Product.findById(id, function(id, err, product) {
if (err) {
res.send(err);
}
res.json({product: product});
});
the params in the callback are wrong, instead you need to remove id and change to:
Product.findById(id, function(err, product) {
if (err) {
res.send(err);
}
res.json({product: product});
});
Hope this helps.

Ember doesn't recognize model data in subfolder

The following structure of routes works fine for me.
But whenever I moved faculty.js inside the faculty folder, my template stops recognizing the data. The static view elements still show up correctly, but the data model is logged as null. How can I fix it?
faculty.js
import Ember from 'ember';
export default Ember.Route.extend({
model(){
return {name:"Janusz", lastname:"Chudzynski", department:"Test"};
}
});
faculty.hbs
{{outlet}}
<h2>Faculty</h2>
{{log model}}
{{faculty-single facultyModel=model}}
Router
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('colleges');
this.route('departments');
this.route('faculty',{path:'/faculty'});
//this.route('faculty');
});
export default Router;
Console log
null
The hierarchy of your folders should closely mirror the hierarchy of your router. In your case you have the following:
Router.map(function() {
this.route('colleges');
this.route('departments');
this.route('faculty');
});
This means that all of them are directly under the application route, being the correct file structure:
app
routes
colleges.js
departments.js
faculty.js
For /app/routes/faculty/faculty.js to work, you would need to have a faculty route nested inside a faculty route:
Router.map(function() {
this.route('colleges');
this.route('departments');
this.route('faculty', function() {
this.route('faculty');
});
});
Since names concatenate, the parent route's full name is faculty, and the nested route's full name is faculty.faculty.

How do I access the variable of a dynamic route in EmberJS

I've done
ember g route auth
ember g route auth/pending
Which then gave me :
app/
routes/
auth/
pending.js
auth.js
and my router has
this.route('auth', function() {
this.route('pending', { path: '/pending/:steamid/:token'});
});
Which everything is fine, when I visit
http://localhost:4200/auth/pending/1/2
The page loads, but how do I access :steamid and :token outside of the model.
I'd like to use it so that I can set values in my session service
Like:
import Ember from 'ember';
export default Ember.Route.extend({
session: Ember.inject.service(),
steamID: this.get(// Params Some How),
token: this.get(// Params some How)
thing(params) {
this.get('session').set('tokenID', token),
this.get('session').set('steamID', steamID)
}
});
^^ Pseudo code to express what I'm trying to accomplish.
While it's not in the website documentation, looking at the source code of the Transition object passed to some Route hooks (e.g. afterModel and beforeModel) it have a params property which contains the dynamic segment params.
So you can, for example:
import Ember from 'ember';
export default Ember.Route.extend({
session: Ember.inject.service(),
thing(params) {
// Do some check and returns the result
},
beforeModel (transition) {
if (!this.thing(transition.params)) {
transition.abort();
this.transitionTo('/login');
}
}
});
You can set them in your service from many different hooks:
import Ember from 'ember';
export default Ember.Route.extend({
session: Ember.inject.service(),
/* Access from beforeModel */
beforeModel(transition) {
this.get('session').setProperties({
tokenID: transition.params.token,
steamID: transition.params.steamid
});
},
/* Access from model */
model(params, transition) {
this.get('session').setProperties({
tokenID: params.token,
steamID: params.steamid
});
}
});
If you ask me model hook is the best choice. Especially if you want your query params to refresh the model every time they change (see guide).

how to receive variables sent by transitionToRoute

I read at
http://emberjs.com/guides/controllers/
the following code:
I have a search box and want to send the value of the search box to the SearchController.
App.ApplicationController = Ember.Controller.extend({ // the initial
value of the `search` property search: '',
actions: {
query: function() {
// the current value of the text field
var query = this.get('search');
this.transitionToRoute('search', { query: query });
} } });
How can i get the query parameter in the SearchController and then show it in search.hbs?
I am working with ember- cli.
The router is
import Ember from 'ember';
var Router = Ember.Router.extend({
location: NENV.locationType
});
Router.map(function() {
this.route('search');
});
export default Router;
I set up a route under routes/search.js
export default Ember.Route.extend({
model : function (params) {
console.debug("hi");
return params;
},
setupController: function(controller,model) {
var query = model.query;
console.debug("query is");
console.debug(query);
}
});
When debugging i get an error:
ember More context objects were passed than there are dynamic segments
Thanks,
David
You need to define your search route to be dynamic, so if you change your route definition to something like this
Router.map(function() {
this.resource('search', {path: '/search/:query});
})
This should work as you are expecting. Let me know if anything.
Cheers!