Having a bit of trouble with iron router and passing in a custom id from a collection.
Some context: I have a collection of "groups" in which they all have their own special id other than the default _id that is auto generated. I am trying to make a route that is like
" localhost:3000/groups/:groupid "
so each group will have its own rendered template with the groups information.
HTML :
<template name="Group">
<h1>Group: {{groupName}}</h1>
</template>
CLIENTSIDE:
grabbing a groupid from a session...
I tested this and it works so its not an issue with grabbing it from the session but rather with the router
var groupid = Session.get('groupID');
Router.go('/groups/:_id',{_id: groupid})
ROUTER:
Router.route('/groups/:_id', function () {
this.render('Group', {
data: function () {
return GroupsList.findOne({_id: this.params._id});
}
});
});
This will render a route with groupid as the params instead of the actual number
UPDATE:
CLIENT
Router.go('/groups/'+ groupid);
ROUTER
Router.route('/groups/:groupid', function () {
this.render('Group', {
data: function () {
console.log(this.params.groupid)
console.log(GroupsList.findOne({groupID: this.params.groupid}))
return GroupsList.findOne({groupID: this.params.groupid});
}
});
});
This seems to get the route to work but it wont render the groupname in the template
From the Iron Router Guide:
Now that we're using named routes in Router.go you can also pass a
parameters object, query and hash fragment options.
Router.go('post.show', {_id: 1}, {query: 'q=s', hash: 'hashFrag'});
However when you call Router.go, you are not passing a route name, but a url.
Try this:
Router.go('/groups/' + groupid);
Router.route('/groups/:_id', function () {
this.render('Group', {
data: function () {
return GroupsList.findOne({groupid: this.params._id});
}
});
});
On a side note from the answer just in case anyone else has this issue , I actually figured out there was an issue in the data type of the "this.params._id" , it seems it was coming up as a data type that was not a string or number and therefore could not be successfully used in the findOne method. In the end I just had to parseInt and this was the solution at the end :
Router.go('/groups/'+ groupid);
Router.route('/groups/:groupid', function () {
this.render('Group', {
data: function () {
var id = parseInt(this.params.groupid)
return GroupsList.findOne({groupID: id});
}
});
});
Related
I currently Angular 1.6 and angular-ui/ui-router
I have a problem with dynamic url which I don't know a limit of parameter
example
www.example.com/name/hello/address/telephone/postcode/city/ .... (n)
or
www.example.com/name/hello/school/age/weight/height/...(n)
or
www.example.com/name/hello/friends/family/age/address
from the example url I need to using ui-route to manage that url and get value parameters from url and just implement only one state.
expected result
let result = [hello,address,telephone,postcode,city, .... (n)];
example route (*only one state handle this case)
.state('person', {
url: '/name/:param1/:param2', (which I want to dynamic)
component: 'person',
resolve: {
search:($transition$) {
return $transition$.params();
}
}
})
Please advice :)
Update :
I found a good solution from this link
Recursive ui router nested views
you can make a function which takes your array input and return an state object.
function generateState(array){
var url = a.reduce(function(url, item){ return url+":"+item+"/" }, "/name/");
return {
url: url,
component: 'person',
resolve: {
search:($transition$)=> {
return $transition$.params();
}
}
}
}
after which you can dynamically register the state using $stateProvider
I've just started to have a play with meteor and I'm slowly moving a
NodeJS/Express app over to meteor. However on my blog section, I can't seem to get a single post _id into the helper. With NodeJS alone, I could use req.params._id.
Using the Differential boilerplate as a starting poing, (still using insecure and autopublish in dev) I have this:
//both/controllers/post.js
PostController = AppController.extend({
waitOn: function() {
return this.subscribe('posts');
},
data: function () {
return Posts.findOne({_id:this.params._id});
}
});
And in the router file
//both/router/router.js
Router.route('/posts/:_id', {
name: 'post'
});
The links on the main blog listing page, to the single posts are formated as follows.
//client/templates/blog/blog.html
<h3>{{ title }}</h3>
Then the helper file which seems to be the issue?
// /client/templates/post/post.js
Template.post.rendered = function() {
};
Template.post.helpers({
data: function () {
return Posts.findOne({_id:this.params._id});
}
});
Template.post.helpers({
createdAtFormatted: function () {
return moment(this.createdAt).fromNow();
}
});
I've tried this.params._id, request.params.id, req.params._id,
And other than setting an on click event and setting the _id in session (I don't like this idea, if it will even work efficiently/effectively). I'm stuck on ideas.
I am working on an admin page that shows a list of the user's orders. For some reason, publication function is not receiving the user's ID as a parameter from my subscription function.
My user object contains the attributes:
_id
userId
confirmed
My orders object contains the attributes:
_id
userId
amount
date
My publication:
Meteor.publish('clientOrders', function(userId) {
console.log('user is ' + userId);
return Order.find({_id: userId});
});
My subscription:
viewClientOrders = RouteController.extend({
loadingTemplate: 'loading',
waitOn: function () {
Meteor.subscribe('clientOrders', this.params._id);
},
action: function() {
this.render('viewClientOrders');
}
});
My route:
Router.route('/viewClientOrders/:id', {name: 'viewClientOrders', controller: 'viewClientOrders', onBeforeAction: requireLogin});
I did a console.log for the userId and it returns null, although I clearly passed a userId parameter (this.params._id) in my subscription function. However, if I pass a parameter of 3, for testing purposes, it will work. Also, I used a similar publication/subscription method to view a client's profile, passing in the exact same parameters and it works fine...
Anyone know what's going on? Thanks!
Make sure you return in your waitOn. Iron Router will only proceed to render if it knows the subscription is ready:
viewClientOrders = RouteController.extend({
waitOn: function () {
return Meteor.subscribe('clientOrders', this.params._id);
}
...
Make sure you've also set a loadingTemplate (docs).
Say I have a collection (of search results, for example) which needs to be populated and a pagination model that needs to take values for current page, total number of pages, etc. In my controller, I make a GET call to an API which returns both search results and pagination information. How, then, can I fetch all this information and parse it into a collection and a separate model? Is this possible?
I am using AirBNB's Rendr, which allows you to use a uniform code base to run Backbone on both the server and the client. Rendr forces me to parse the API response as an array of models, keeping me from being able to access pagination information.
In Rendr, my controller would look like this:
module.exports = {
index: function (params, callback) {
var spec = {
pagination: { model: 'Pagination', params: params },
collection: { collection: 'SearchResults', params: params }
};
this.app.fetch(spec, function (err, result) {
callback(err, result);
});
}
}
I apologize if this is not clear enough. Feel free to ask for more information!
This is super old so you've probably figured it out by now (or abandoned it). This is as much a backbone question as a Rendr one since the API response is non-standard.
Backbone suggests that if you have a non-standard API response then you need to override the parse method for your exact data format.
If you really want to break it up, the way you may want to code it is:
a Pagination Model
a Search Results Collection
a Search Result Model
and most importantly a Search Model with a custom parse function
Controller:
index: function (params, callback) {
var spec = {
model: { model: 'Search', params: params }
};
this.app.fetch(spec, function (err, result) {
callback(err, result);
});
}
Search Model
var Base = require('./base'),
_ = require('underscore');
module.exports = Base.extend({
url: '/api/search',
parse: function(data) {
if (_.isObject(data.paginationInfo)) {
data.paginationInfo = this.app.modelUtils.getModel('PaginationInfo', data.paginationInfo, {
app: this.app
});
}
if (_.isArray(data.results)) {
data.results = this.app.modelUtils.getCollection('SearchResults', data.results, {
app: this.app,
params: {
searchQuery: data.searchQuery // replace with real parameters for client-side caching.
}
});
}
return data;
}
});
module.exports.id = 'Search';
So, I'm trying to build routes in my Ember application dynamically with data from an API endpoint, /categories, with Ember Data. In order to do this, I'm adding a didLoad method to my model, which is called by the controller and set to a property of that controller. I map the route to my router, and all that works fine. The real trouble starts when I try to set up a controller with a content property set by data from the server retrieved by findQuery.
This is the error:
TypeError {} "Object /categories/548/feeds has no method 'eachRelationship'"
This is the code:
window.categoryRoutes = [];
App.Categories = DS.Model.extend({
CATEGORYAFFINITY: DS.attr('boolean'),
CATEGORYID: DS.attr('number'),
CATEGORYNAME: DS.attr('string'),
CATEGORYLINK: function () {
var safeUrl = urlsafe(this.get('CATEGORYNAME'));
categoryRoutes.push(safeUrl);
return safeUrl;
}.property('CATEGORYNAME'),
didLoad: function () {
var categoryLink = this.get('CATEGORYLINK');
var categoryId = this.get('CATEGORYID');
App.Router.map(function () {
this.resource(categoryLink, function () {
// some routes
});
});
App[Ember.String.classify(categoryLink) + 'Route'] = Ember.Route.extend({
setupController: function(controller, model) {
// source of error
this.controllerFor(categoryLink).set(
'content',
this.store.findQuery('/categories/' + categoryId + '/feeds', {
appid: 'abc123def456',
lat: 39.75,
long: -105
})
);
}
});
}
});
Any 'halp' is appreciated!
Also, if I'm doing this completely wrong, and there's a more Ember-like way to do this, I'd like to know.
I figured this out. I got this error because I was passing in a string instead of a real 'type' from the App.Helpers object to an extract method in some custom RESTAdapter code I had overridden.
The solution is to pass in the corresponding model helper in App.Helpers using my custom type name.
Something like this in the overridden RESTAdapter.serializer.extractMany method:
var reference = this.extractRecordRepresentation(loader, App.Helpers[root], objects[i]);