backbone.js routing when query passed to route contains / - backbone.js

My app basically takes some form input and returns a set of results. I have two routes
routes: {
'': 'search',
'search': 'search',
'results/:query': 'results'
},
results: function(query) {
var search = new ResultsSearchView();
var grid = new GridView({ query: query });
}
If the query contains any characters / specifically (can totally happen in this case), they are added to the URL and my route breaks.
I have tried using encodeURI() and encodeURIComponent() bit I'm not having any luck. How are you folks handling such things?

You can use encodeURIComponent when building the URL to convert the / to %2F and then decodeURIComponent inside the route handler to convert them back; the HTML would end looking like this:
no slash
with slashes
and then in the router:
routes: {
'results/:query': 'results'
},
results: function(query) {
query = decodeURIComponent(query);
// Do useful things here...
}
Demo: http://jsfiddle.net/ambiguous/sbpfD/
Alternatively, you could use a splat route:
Routes can contain parameter parts, :param, which match a single URL component between slashes; and splat parts *splat, which can match any number of URL components.
So your HTML would be like this:
no slash
with slashes
and your router:
routes: {
'results/*query': 'results'
},
results: function(query) {
// Do useful things here...
}
Demo: http://jsfiddle.net/ambiguous/awJxG/

Related

AngularJS - ui router - Cannot match url param key with exclamation mark

I have multiple states in my app, which i define using a $stateProvider like this:
.state(STATES.s1,
{
url: "/?refnr"
template: ...
})
.state(STATES.s2,
{
url: "/?details&searchID&pos"
template: ...
})
Now i want to have a third state, where i want to catch all the urls containing a specific url param, which includes an exclamation mark. This is the parameter 'emp!' and looks like this in url with a value ".../?emp!=45".
I defined this as my state:
.state(STATES.s3,
{
url: "/?emp!"
template: ...
})
Does not work. It does not match the url.. I also tried to use a $urlMatcherFactoryProvider and supply a compiled matcher as url, but same result.
I also tried to use the encoded version of ! in my state url definition like this:
url: "/?emp%21"
still same result.
Why is that so? How can i match these urls?
You can use a trick of fake parameter as this sample and this will handle all your urls ending with "/?emp!
.state(STATES.s3,
{
url: "/:anyurl/?emp!"
template: ...
})
Try something like this. The expression between curly braces is a regular expression matching your criteria.
.state(STATES.s3, {
url: "/{^\?.*emp!$}"
template: ...
})
That regex will match urls that start with the ?, ends with ! and has emp before !. like:
?hemp!
?param=value&temp!

Backbone Route not firing

This should be super basic but I can't get routing working. I should mention that the application is located in a subdirectory called /dist/. Here's my code:
var QuestionRouter = Backbone.Router.extend({
routes: {
"/dist/" : "startTest"
"dist/:id": "getModel"
},
startTest: function(){
console.log('home called')
},
getModel: function(){
app.getModel(id);
}
});
var app = new QuestionView;
var appRouter = new QuestionRouter;
Backbone.history.start({pushState: true});
The URL to trigger this route is:
www.example.com/dist/
www.example.com/dist/12345
Any help would be appreciated.
You'll need to use # (hash symbol).
Backbone routers are used for routing your applications URL's when
using hash tags(#)
This is a quote from a Backbone tutorial: What is a router?
See Backbone's Router documentation
Then your routes would be:
www.example.com/#/dist/
www.example.com/#/dist/12345
You can also use Backbone routes without hashes.
Ok So I was able to work this out:
My route hash should look like this:
routes: {
"" : "startTest",
":id": "getModel"
}
I had to remove pushState: true, with this in place the route wasn't being triggered, not sure why:
Backbone.history.start();

Backbone pushState and Laravel 4 - Routes won't work

I've got a very simple setup of laravel 4 with 1 controller for trips.
Now another simple setup of Backbone with a Router and routes to regular routes like trips, trips/create. I want to use pushState: true to have nice URL but I can't seem to get it to work. When I try to reach the URLs it sends me to the page served by the server with my json data.
However, if I type: www.mysite.com/#trips I am "redirected" to www.mysite.com/trips and then my method for this specific route triggers.
Here's my Router:
App.Router = Backbone.Router.extend({
routes: {
'': 'index',
'trips': 'trips',
'trips/create': 'newTrip',
'trips/:id': 'showTrip'
},
index: function(){
},
trips: function(){
console.log('All trips') ;
},
newTrip: function(){
console.log('New trip') ;
},
showTrip: function(id){
console.log('trips id:' + id) ;
}
});
This is probably caused by the Backbone router not being able to match the URL to your Backbone routes. To debug, add this to your routes:
'*actions': 'defaultAction'
Then in the router add:
defaultAction: function(path) {
console.log('Route "' + path + '" not defined, redirecting to homepage!');
}
You will probably see that the path is different from anything in your routes. To fix this, you need to tell Backbone the root of your paths. You do this while activating pushstates.
Backbone.history.start({
pushState: true,
root: 'http://mydomain.com/myapplication/'
});
Hope this helps.

Backbone.Router wrong match fragment

I have the following routes object:
routes: {
"*defaults": "home",
'#test': 'test'
}
Here's the url options:
myApp.html // home is called as desired
myApp.html#test // home is called instead of test
What did I miss?
Per the docs, you don't need the hash mark in the route (that's implied by the Backbone routing convention). Also, the "*defaults" route is going to catch everything, so you should put it last after more specific routes. So, like this:
routes: {
'test': 'test'
"*defaults": "home",
}
Should result in myApp.html#test getting routed to test.

Programmatically adding routes to Backbone.Router?

Here is my application-router.js file where i'm creating Backbone.Router object with just only few routes:
var App = App || {};
App.Router = Backbone.Router.extend({
routes : {
'' : 'showDashboard', // Not shown
'*other': 'showModalError'
},
defaultRoute : function(other) { $('#modal404').modal(); }
});
In main javascript file application.js i'd like to programmatically add routes. I've tried with route() function and it doesn't work, routes are not added. It works however passing an object to the "constructor", but that will override already defined routes:
// This works and overrides all defined routes in App.Router
var router = new App.Router({ routes : { '/test/me' : 'testRoute' } });
// This is not working
router.route(ExposeTranslation.get('customers.new.route'), 'newCustomer');
router.route('/test/me/again', 'testAgainRoute');
In fact console.log(App.Router) shows:
routes Object { /test/me="testRoute"}
I suppose i'm missing something i can't figure out, i'm beginning learning this little piece of powerful javascript.
Your router.route calls are working, those calls aren't your problem. When you call route to add a new route, the new route goes at the end of the routing list. In particular, the routes that are added by your route calls go after '*other' and '*other' will match anything so your new routes will be effectively ignored.
Try removing your '*other' route from routes and adding it after your two route() calls:
routes : {
'' : 'showDashboard' // Not shown
},
router.route(ExposeTranslation.get('customers.new.route'), 'newCustomer');
router.route('/test/me/again', 'testAgainRoute');
router.route('*other', 'showModalError');
The routes aren't stored in App.Router object, they're stored inside Backbone.history:
route: function(route, name, callback) {
// ...
Backbone.history.route(route, _.bind(function(fragment) {
//...
}, this));
return this;
},
That's why your console.log(App.Router) doesn't say anything helpful.

Resources