How to ignore trailing slash in marionette routes? - javascript

I am defining routes in Marionettejs as follows:
var Mn = require('backbone.marionette');
var Router = Mn.AppRouter.extend({
routes: {
'': 'default',
'login': 'login', // http://localhost:8080/#/login
'signup': 'signup' // http://localhost:8080/#/signup
},
initialize: function () {
var initData = this.getOption('keyInOptions');
},
// below are route functions
default: function () {
console.log('this is default route');
},
login: function () {
console.log('this is login route');
},
signup: function () {
console.log('this is signup route');
}
});
module.exports = Router;
Then in the browser:
http://localhost:8080/#/login
successfully triggers the login route, but
http://localhost:8080/#/login/
(add one forward slash at the end) will not trigger login route function. I know I can define another route entry:
...
'login': 'login',
'login/': 'login',
...
to solve this problem, but this solution will double the entries in router definition. Is there a better way to trigger the same route handler for login and login/ ?

Have you tried surrounding the trailing slash with parentheses? Like the following:
routes: {
'login(/)': 'login'
}
From the backbone documentation:
Part of a route can be made optional by surrounding it in parentheses
(/:optional).

Related

Doing something different for main route in meteor iron router

Im using Iron-Route for routing in my meteor app. As I have multiple modules and I want to avoid multiple coding, I put the filter for authentification (role) to the core package:
core package
var filters = {
authenticate: function () {
var user;
if (Meteor.loggingIn()) {
this.layout('login');
this.render('loading');
} else {
user = Meteor.user();
if (!user) {
this.layout('login');
this.render('signin');
return;
}
this.layout('StandardLayout');
this.next();
}
}
}
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound',
before: filters.authenticate
});
Router.route('/', function () {
this.render('contentTemplate', { to: 'content' });
this.render('navigationTemplate', { to: 'navigation' },)
});
other packages
...just need this:
Router.route('/article/:_id', {
name: 'article',
yieldTemplates: {
'navigationPage': { to: 'navigation' },
'contentPage': { to: 'content' }
}
});
Now there is a check on every module (route) before displaying anything.
But I need an exception for the front page. The main page Route.route('/') should be accessed also by user who are not logged in. How do I do that?
You can use the onBeforeAction hook from iron:router as shown below.
This solution assumes your login route is named 'login' . But can be modified to fit your needs.
./client/lib/hoooks/router.js
Router.onBeforeAction(function () {
// all properties available in the route function
// are also available here such as this.params
if (!Meteor.userId()) {
//code for action to be taken when user is not logged in
this.redirect('login');
this.stop();
} else {
this.next();
}
},{except: ['homeRouteName'] });
NB: Replace 'homeRouteName' with the name of your route at '/'

How to define and trigger Backbone route with get params?

I have the following routes:
var Workspace = Backbone.Router.extend({
routes: {
"": "index"
},
index: function() {
...
}
});
At now I can trigger this route like this Backbone.history.navigate('', true); and all works fine. But now I need to add GET params to that router to be possible trigger and handle route like this:
var Workspace = Backbone.Router.extend({
routes: {
"?:query": "index"
},
index: function(query) {
...
}
});
But unfortunately my index callback don't get executed when I trigger Backbone.history.navigate('?needShowPopup=true', true);
How should I define and trigger route to pass and handle GET parameters for my index route?
I would do that
var Workspace = Backbone.Router.extend({
routes: {
"*": "index"
},
index: function() {
var query = location.search;
// work with query
}
});
Let me know if you get a problem.

ReactJS redirect

I'm using ReactJS and react-router in my application. I need to do next thing: when user open the page - to check, if he logged in or no, and if yes, then to do redirect to /auth page. I'm doing next thing:
componentWillMount: function() {
if (sessionStorage["auth"] == null) {
this.transitionTo("/auth");
}
},
In browser url it really do redirect to /auth, render the /auth page and after override it with current component. So here the question: how to cancel rendering for the current component, or how to do redirect in other way? Thanks.
Take a look at the react-router example auth-with-shared-root: https://github.com/rackt/react-router/tree/master/examples/auth-with-shared-root
What they basically do is to check on an enter of a route where to go. Take a look in file config/routes.js line 36, 51 and 89:
{ onEnter: redirectToLogin,
childRoutes: [
// Protected nested routes for the dashboard
{ path: '/page2',
getComponent: (location, cb) => {
require.ensure([], (require) => {
cb(null, require('../components/PageTwo'))
})
}
}
// other protected routes...
]
}
This route will call function redirectToLogin when the route /page2 is entered or pushed to. The function can than check, if the user is authenticated with auth.loggedIn()
function redirectToLogin(nextState, replace) {
if (!auth.loggedIn()) {
replace({
pathname: '/login',
state: { nextPathname: nextState.location.pathname }
})
}
}
If the user is not logged in, the function will replace the route to /login, where the user can authenticates itself.

Backbone non-default root url

I'm trying to integrate Backbone inside a PHP CMS.
The root url for my Backbone app is:
http://localhost/administrator/index.php?option=com_test&controller=product.list
I have setup my router like this:
var AppRouter = Backbone.Router.extend({
routes: {
'': 'test',
}
});
var initialize = function () {
var router = new AppRouter;
router.on('test', function () {
console.log('match');
});
Backbone.history.start({
pushState: true,
root: '/administrator/index.php?option=com_test&controller=product.list'
});
router.navigate('/', {trigger: true});
};
The navigate function is correctly called but the route never matches.
I tried to add a trailing backslash in the root, but it doesn't not change anything.
The problem is that you should either add test method to Router like that:
var AppRouter = Backbone.Router.extend({
routes: {
'': 'test',
},
test: function(){
console.log('test route');
}
});
or listen to route:test event:
router.on('route:test', function () {
console.log('match');
});
because Backbone.Router triggers routes names when matched with prefix route:

Ember.js Error in specifying URL type of location='history' in App.Route

I have started learning the ember.js framework and I am stuck at how to use the setting of the URL type feature that the framework has.
http://emberjs.com/guides/routing/specifying-the-location-api/
I have this simple application.js
App = Ember.Application.create();
App.Router.reopen({
location: 'history'
});
App.Router.map(function () {
this.route('about');
});
App.ApplicationRoute = Ember.Route.extend({
model: function () {
return appdata;
}
});
App.IndexRoute = Ember.Route.extend({
setupController: function (controller) {
// Set the IndexController's `title`
controller.set('indextitle', "My Index title");
},
renderTemplate: function () {
this.render({ outlet: 'indexoutlet' });
}
});
App.AboutRoute = Ember.Route.extend({
model: function () {
return appdata;
},
renderTemplate: function () {
this.render({ outlet: 'aboutoutlet' });
}
});
var appdata = { mytext: '', theplaceholder: 'Enter new text', attr:'Yeap!' }
If I don't use the
App.Router.reopen({
location: 'history'
});
the application works fine and it goes to the 'about' route by appending the URL the '~/EmberjsTest.aspx#/about' as it supposed to do.
However because I do not like the hash symbol in the URL of the page, I would prefer if it was removed and to do that the guide says we should put this code:
App.Router.reopen({
location: 'history'
});
But when I do it I get an error in the Chrome console saying:
'Assertion failed: The URL '/EmberjsTest.aspx' did match any routes in your application'
What am I doing wrong?
Thanks in advance
If you want to use the history API then you have two options.
Serve your Ember app from '/' so that Ember can just work with it's "normal" index/root route.
Create a route in your Ember app that can handle '/EmberjsTest.aspx'.
this.route("index", { path: "/EmberjsTest.aspx" });
Note that if you go with option 2 you'll probably have to update all of your routes to include '/EmberjsTest.aspx' in their paths.
this.resource("posts", {path: "/EmberjsTest.aspx/posts" })

Categories