Meteor: how to use different routes for the same template - javascript

I want to pass a param by the router
I have been trying :
Router.route('/someURL/:id', {
name: 'someTemplate',
data: function() {
var myData = someCollection.findOne({_id:this.params.id});
myData.someParam = true;
return myData;
}
});
Router.route('/anotherURL', {
name: 'someTemplate',
data: function() {
return {someParam:false};
}
});
but it doesn't work
This is my error:
Error: Handler with name 'someTemplate' already exists.
How can i solve it.?
Note: I need this "someParam"

The name is a name for the route not the template you want to use. Route names are a unique identifier per route much like the url and can be used to call the route without using the full url. You want something like:
Router.route('/someURL/:id', {
name: 'someName',
template: 'someTemplate',
data: function() {
var myData = someCollection.findOne({_id:this.params.id});
myData.someParam = true;
return myData;
}
});
Router.route('/anotherURL', {
name: 'someOtherName',
template: 'someTemplate',
data: function() {
return {someParam:false};
}
});

Related

How do I pass a dynamic page :id to $http.get url in Vue.js

I have have view router set up:
router.map({
'/tracks/:id': {
component: SingleTrack
}
})
And this is my component (which works with a hard coded URL):
var SingleTrack = Vue.component('track', {
template: '#track-template',
data: function() {
return {
track: ''
}
},
ready: function() {
this.$http.get('//api.trax.dev/tracks/1', function (data) {
this.$set('track', data.track)
})
}
});
How do I pass the url/:id to the end of the $http.get string so i can grab the correct data dynamically when that route in loaded, something like:
ready: function(id) {
this.$http.get('//api.trax.dev/tracks/' + id, function (data) {
this.$set('track', data.track)
})
}
You should be able to get the route parameter from the component $route property :
var itemId = this.$route.params.id;
this.$http.get('//api.trax.dev/tracks/' + itemId, function (data) {
this.$set('track', data.track)
})
See more details in vue.js router documentation
For Best Practises:
index.js(router)
{
path: '/tracks/:id',
name: 'SingleTrack',
component: SingleTrack,
props: (route) => {
const id = Number.parseInt(route.params.id);
return { id }
},
}
SingleTrack.vue
props: {
id: {
type: Number,
required: true,
},
},
mounted(){
this.$http.get('//api.trax.dev/tracks/' +this.id, function (data) {
this.$set('track', data.track)
})
}

Manage Ember Multiple RSVP Promises on the same route

I am working with the GitHub API in order to load models in a specific route
I am doing two promises one for my personal github details : https://api.github.com/users/user and the other one for my GitHub repositories https://api.github.com/users/user/repos
I can load the models separately but the problem is that i don't figure on how to load both models at the same time in my specific route.
See the code
var IndexRoute = Ember.Route.extend({
model: function(params) {
var url, self, git;
self = this;
git = this.store.createRecord('git',{});
url = 'https://api.github.com/users/user';
return new Ember.RSVP.Promise(function(resolve, reject) {
return Ember.$.getJSON(url, function(data) {
var item = [];
git.setProperties({
name: data.name,
login: data.login,
location: data.location,
company: data.company,
followers: data.followers,
following: data.following
});
item.pushObject(git);
return resolve(item);
});
});
},
model: function(params){
var self, url, repoListProxy;
self = this;
url = 'https://api.github.com/users/user/repos';
repoListProxy = Ember.ArrayProxy.create({
content: []
});
return new Ember.RSVP.Promise(function(resolve, reject) {
return Ember.$.getJSON(url, function(repos) {
if (repos.length) {
repos.toArray().forEach(function(item, index, arr){
var repo;
repo = self.createReposList(item, repoListProxy);
});
repos = repoListProxy.get('content');
return resolve(repos);
}
});
});
},
createReposList: function(repo, arr){
var record
record = this.store.createRecord('repo',{}),
record.setProperties({
name: repo.name,
description: repo.description
})
arr.pushObject(record);
return record;
},
});
How can i load these multiple models with Ember.RSVP.Promise in my specific route?
Since the code you posted is too long to read i didn't implement solution based on it. Here's a common example of loading mutliple promises within a single route in the model hook.
model: function() {
var store = self.get('store');
var someRecord = store.createRecord('foo/bar', {});
var somePromise = imported_promise(someRecord);
return Ember.RSVP.hash({
accessRights: somePromise,
itemData: somePromise.then(function(resolved) {
// Do something here, promise is resolved.
})
myRecord: someRecord,
});
},
Now if you need to access anything from route in the template or controller.
you would first reference to model and then the property.
{{model.myRecord}} or this.get('model.myRecord')
Since you're a nice guy for downvoting me i decided i'd write it for you.
I reccomend using Ic-AJAX : https://github.com/rwjblue/ember-cli-ic-ajax for async calls when you cant use store.find
model: function() {
var store = this.get('store');
var userUrl = 'https://api.github.com/users/user';
var reposUrl = 'https://api.github.com/users/user/repos';
var usersPromise = function() {
return ic.ajax.request(userUrl).then(function(data) {
return store.createRecord('git', {
name: data.name,
login: data.login,
location: data.location,
company: data.company,
followers: data.followers,
following: data.following
})
};
};
var repositoriesPromise = function() {
return ic.ajax.request(reposUrl).then(function(repos) {
return repos.map(function(repo) { // map returns new array no need to write container = [] . container.push(bla)
return store.createRecord('repos', {
name: repo.name,
description: repo.description
});
})
};
}
return Ember.RSVP.hash({
users: usersPromise,
repositories: repositoriesPromise
});
},
Since you're still using a different approach i went ahead and googled its syntax
var gituserPromise = function() {
return Ember.$.ajax(userUrl, {
success: function(data) {
return store.createRecord('git', {
name: data.name,
login: data.login,
location: data.location,
company: data.company,
followers: data.followers,
following: data.following
})
},
error: function(reason) {
reject(reason);
}});
};
return Ember.RSVP.hash({
gitUser: gituserPromise()
});
In hbs i can now do {{model.gitUser.name}}
New link to it http://emberjs.jsbin.com/rutezi/2/edit?html,js,output

Transform data before rendering it to template in meteor

I want to return a single document with the fields joined together. That is, a result like as follows
{
_id: "someid",
name: "Odin",
profile: {
game: {
_id: "gameid",
name: "World of Warcraft"
}
}
}
I have a route controller which is fairly simple.
UserController = RouteController.extend({
waitOn: function () {
return Meteor.subscribe('users');
},
showAllUsers: function () {
this.render('userList', {
data: Meteor.users.find()
})
}
});
I've tried changing my data like so:
this.render('userList', {
data: Meteor.users.find().map(function (doc) {
doc.profile.game = Games.findOne();
return doc;
})
});
However, this does not have the intended effect of adding "game" to the user. (and yes, Games.findOne() has a result)
How can you transform the results of a cursor in meteor and iron:router?
Try defining your data as a function so it can be dynamically re-executed when needed.
UserController = RouteController.extend({
waitOn: function () {
return Meteor.subscribe('users');
},
showAllUsers: function () {
this.render('userList', {
data: function(){
return Meteor.users.find().map(function (doc) {
doc.profile.game = Games.findOne();
return doc;
});
}
});
}
});
Given your use of easy search, what might be simpler is just to define a template helper for profile
Template.userList.helpers({
profile: function(){
var game = Games.findOne({_id: this.gameId});
return { game: { _id: game._id, name: game.name }};
}
});
This assumes a single game per user. If you have more than one then you can iterate over a cursor of Games instead.

Cannot access this.params variable in data: property in iron router

The following code does not work when the url is /company/martin:
this.route('scheduledTasks', {
path: '/company/:name',
data: {
items:
function(){
return scheduledTasks.find({company: this.params.name});
}
}
While this does work:
this.route('scheduledTasks', {
path: '/company/:name',
data: {
items:
function(){
return scheduledTasks.find({company: "martin"});
}
}
I tried several solutions, but it seems that this.params.name does not exist or cannot be accessed??
this.params.name needs to be evaluated within the context of the route, and I believe that only can happen if data is a function and not an object literal. Try this:
this.route('scheduledTasks', {
path: '/company/:name',
data: function() {
var company = this.params.name;
return {
items: function() {
return scheduledTasks.find({company: company});
}
};
}
});

Override parse function on Backbone Collection

I have a backbone collection:
var user = new Backbone.Collection.extend({
url: '/user',
parse: function (response) {
return response.lunch;
return response.dinner;
}
});
which returns a json like this:
[
{
lunch: [{
appetizer : 'bagel',
maincourse: 'steak',
desert: 'sweets'
}]
},
{
dinner: [{
appetizer : 'chips',
main: 'rice',
desert: 'sweets'
}]
}
]
I want to combine both response.lunch and response.dinner and have a common collection: I tried:
parse: function (response) {
var collection1 = response.lunch;
var collection2 = response.dinner;
return collection1.add(collection2.toJSON(), {silent : true});
}
But it doesnot work. Also how do i do a each function to override all main with maincourse? I tried:
this.collection.each(function(model) {
var a = model.get("main");
model.set({a: "maincourse"});
}
Any help would be appreciated. Thanks!
I'm guessing that you want to merge lunch and dinner so that your collection ends up with { appetizer : 'bagel', ... } and { appetizer : 'chips', ... } inside it. If so, then simply concat the two arrays together:
parse: function(response) {
return response.lunch.concat(response.dinner);
}
If you want to rename all the main attributes to maincourse then you'd want to use get to pull out the mains, unset to remove them, and then set to put them back in with the new name:
var maincourse = model.get('main');
model.unset('main', { silent: true });
model.set('maincourse', maincourse, { silent: true });
or just edit attributes directly:
model.attributes.maincourse = model.attributes.main;
delete model.attributes.main;
or better, just rename the attribute in your parse method.

Categories