Meteor iron:router routecontroller change context of this - meteor

I have a function that checks if the user is logged in and it looks like this:
var requireLogin = function () {
if (! Meteor.user()) {
if (Meteor.loggingIn()) {
this.render(this.loadingTemplate);
} else {
this.render('accessDenied');
}
} else {
this.next();
}
};
It is a simple function and it works when i use it on a hook like this:
Router.onBeforeAction(requireLogin, {only: 'postSubmit'});
However, when i try to call it in an extended routecontroller like this:
LogInController = RouteController.extend({
onBeforeAction: function () {
requireLogin();
}
});
It does not work. However i can just paste the context of the function into onBeforeAction in the logincontroller and it will work.
LogInController = RouteController.extend({
onBeforeAction: function () {
if (! Meteor.user()) {
if (Meteor.loggingIn()) {
this.render(this.loadingTemplate);
} else {
this.render('accessDenied');
}
} else {
this.next();
}
}
});
so what do i need to do? Do i need to pass the value of this into the requireLogin function or is there a smarter way?

I believe that you can solve this problem by using javascript's bind function, which binds the function to the context:
LogInController = RouteController.extend({
onBeforeAction: function () {
requireLogin.bind(this)();
}
});
However, that might not even be necessary, if you just pass the function as value directly, thereby avoiding the redirection that may cause the change in context:
LogInController = RouteController.extend({
onBeforeAction: requireLogin
});

Related

Meteor How to call one template helper into another helper?

How i can access one template helper into another. I have 2 templates
Right sidebar path is
app\client\templates\shared\sidebar
my_trb path is
app\client\templates\pages\my_trb
on my_trb page i am showing list of all added memebrs in my account and same thing i need to call in sidebar helper. So is there way to call my_trb template helper into sidebar? This is helper in my_trb
Template.MyTribes.helpers({
'myTrb' () {
let tribIOwn = Meteor.user().trb_i_own;
let trb = [];
tribIOwn.forEach(function (t) {
trb.push(Trb.findOne({_id: t}));
});
return trb;
},
});
This is full code of tribes_controller.js
TrbController = RouteController.extend({
subscriptions: function() {
this.subscribe('users').wait();
this.subscribe('trb', this.params._id).wait();
},
waitOn: function () {
this.subscribe('trb',Meteor.userId());
this.subscribe('tribeArgs', this.params._id);
},
data: function () {
return Trb.findOne({_id: this.params._id});
},
// You can provide any of the hook options
onRun: function () {
this.next();
},
onRerun: function () {
this.next();
},
//onBeforeAction: function () {
// this.next();
//},
onBeforeAction: function () {
if (!Meteor.userId()) {
this.render('Splash');
} else {
if (!Meteor.user().username) {
this.render('AddUsername');
} else {
this.next();
}
}
},
action: function () {
this.render();
},
onAfterAction: function () {
},
onStop: function () {
},
editTribe: function () {
this.render('EditTribe');
}
});
For common / shared code that needs to be accessed by more than one Template it makes sense to define a global helper using Template.registerHelper.
For your helper this would look like this:
app\client\templates\shared\helpers
// import { Trb } from ....
Template.registerHelpers('myTrb', function myTrb () {
const user = Meteor.user();
if (! user) return [];
const tribIOwn = user.trb_i_own;
const trb = [];
tribIOwn.forEach(function (t) {
trb.push(Trb.findOne({_id: t}));
});
return trb
})
(Note, that I changed a bit, since Meteor.user().trb_i_own would crash if there is no logged in user.)
Now you can remove the helper on the my_trb Template and call it from my_trb and the sidebar as well.

Proper syntax for iron-router's Router.route?

I have the following code for my iron-router signOut route in a Meteor JS app. I am trying to convert the deprecated Router.map to the new Router.route syntax but having difficulty getting the onBeforeAction and onAfterAction to work. What is the proper Router.route syntax for the following code block?
Router.map(function () {
// sign-out the user then redirect them to the home page
this.route('signOut', {
path: '/sign-out',
onBeforeAction: function () {
if (Meteor.userId()) {
Meteor.logout()
}
this.next();
},
onAfterAction: function () {
this.redirect('/');
}
});
});
Router.route('/sign-out', function() {
//here you put things you wanna render, it's empty since you just want to logout and redirect
}, {
name: 'signOut',
onBeforeAction: function () {
if (Meteor.userId()) {
Meteor.logout()
}
this.next();
},
onAfterAction: function () {
Router.go('/');
}
});
And I think you should add waitOn function, cause there might be no Meteor.user() object at first if not subscribed earlier

SubsManager with Iron-Router new API

any idea how I could connect SubsManager with IR new API?
I use syntax like:
Router.route('/', function () {
this.subscribe('some_subscription').wait();
if (this.ready()) {
//something
} else {
//something
}
},{
name:'1234'
});
Tried subs.subscribe('some_subscription').wait(); but it threw error
Template never rendered, did you forget to call 'this.next()?(of course I initialized object subs)
From the subscription manager docs https://github.com/meteorhacks/subs-manager/#limitations
At the moment, the following functionality doesn't work (patches welcome):
.........................
...............
chained .wait() call in Iron Router (issue - you can use waitOn instead)
so subs.subscribe('some_subscription').wait(); this will throw error
From Iron-router docs https://github.com/EventedMind/iron-router#migrating-from-094
onRun and onBeforeAction hooks now require you to call this.next(), and no longer take a pause() argument. So the default behaviour is reversed. For example, if you had:
Router.onBeforeAction(function(pause) {
if (! Meteor.userId()) {
this.render('login');
pause();
}
});
You'll need to update it to
Router.onBeforeAction(function() {
if (! Meteor.userId()) {
this.render('login');
} else {
this.next();
}
});
Make sure that this.next() is called on onRun and onBeforeAction blocks
and also organize your router code like in lib/routes.js file
//configuration
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'error'
});
//keep all your routers under a common function
Router.map(function() {
this.route("index",{
path:"/",
onBeforeAction:function(){ //do something },
data:return something,
onAfterAction
});
});
Finally my answer to the question any idea how I could connect SubsManager with IR new API?
Router.map(function() {
this.route("index",{
path:"/",
waitOn: function() {
return subs.subscribe('some_subscription');
},
data:function(){
if (this.ready()) {
//do something like this.render("loading")
} else {
//do something this.render("mytemplate")
}
},
onAfterAction
});
});

MeteorJS, iron-router, filters, redirection, delay

Router._filters = {
isLoggedOut: function (pause) {
if (!Meteor.userId()) {
return this.redirect('home');
} else {
this.next();
}
},
isLoggedIn: function (pause) {
if (Meteor.userId()) {
return this.redirect('dashboard');
} else {
this.next();
}
}
};
filters = Router._filters;
Router.onBeforeAction(filters.isLoggedOut, { except: [
'home'
]});
Router.onBeforeAction(filters.isLoggedIn, { only: [
'home'
]});
I'd like to make filter in iron-router which makes redirect to 'home' when user is not logged in and to 'dashboard' if user is logged in. Everything works, but in the first case dashboard is shown for a second and then redirect is done. How can I get rid of this delay?
I would create a custom controller.
// Global Router configuration
Router.configure({
loadingTemplate: 'loading'
notFoundTemplate: 'notFound'
controller: BaseController
});
The code above says: "For all existing paths, use the BaseController"
Your BaseController should look like this
BaseController = RouteController.extend({
action: function() {
if(!Meteor.userId()) {
// this.render('home');
// this.go('home);
this.redirect('home');
}
else {
// this.render('dashboard');
// this.go('dashboard');
this.redirect('dashboard');
}
}
})
If you need more controll for each site,give your specific site a controller, which inherit from the BaseController. It should looks like this
// Global Router configuration
// Remove the controller property!
Router.configure({
loadingTemplate: 'loading'
notFoundTemplate: 'notFound'
});
Router.map(function() {
this.route('contact', {
path: '/contact',
controller: 'ContactController'
})
});
Your ContactController should looks like this
ContactController = BaseController.extend({
// Do something with this given route,
// e.g., give it a name property or so
name: 'contact',
action: function() {
}
})
For more information, check the Iron.Router guide.
https://github.com/EventedMind/iron-router/blob/devel/Guide.md#route-controllers

How to Call Pagemethod in Angular js Service

i am new in Angular js.
Static Method in Code Behind
[WebMethod]
public static string GetPracticeLocations()
{
return "[{ id: 1, name: Test AccountName}]";
}
Angular JS Service
appSettings.service('PracticeLocationsService', function () {
this.getPracticeLocations = function () {
var PracticeLocationsData = PageMethods.GetPracticeLocations();
return PracticeLocationsData;
};
});
i want to know how to implement page method in Angular JS.
Any helpful suggustein apricited
Thanks
Probably I'm too late, but you could use defer to call a page method and return a promise,
var getPracticeLocations = function () {
var deferred = $q.defer();
PageMethods.GetPracticeLocations(function (response) {
if (response) {
deferred.resolve({ result: angular.fromJson(response) });
} else {
deferred.resolve({ result: null });
}
},
function (msg, code) {
deferred.reject(msg);
});
return deferred.promise;
};
You want to look at factory() and $http
pseudo code:
angular.factory("PageMethods", ["$http", function($http){
return {
GetPracticeLocations : function(){
return $http.get("/someurl");
}
}
}]);

Resources