1

I'm trying to configure Router with Backbone.js and receiving an exception at line 1414 of backbone.js 1.1.2

The error exists with Safari and Chrome:

[Error] TypeError: 'undefined' is not a function (evaluating 'Backbone.$(window).on('hashchange', this.checkUrl)')
start (backbone.js, line 1414)
(anonymous function) (index.html, line 27)

Here's the index.html file, line 27 is Backbone.History.start()

<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<head>
    <link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
    <div class="container">
    </div>
    <script src="../jquery.js"></script>
    <script src="../underscore.js"></script>
    <script src="../backbone.js"></script>
    <script src="../json2.js"></script>

</body>

<!-- BACKBONE -->
<script type="text/javascript">
    (function($) {
        var PageRouter = Backbone.Router.extend({
            routes: {
                '': 'index'
            }
        });
        var pageRouter = new PageRouter();
        pageRouter.on('index', function() {
            console.log('hey');
        });
        Backbone.history.start();
    })(jQuery)
</script>
</html>

I can't find many resources to help out, and most of the pre-existing resources emphasize the allocation of the Router, and I feel it's implemented correctly. Also, I don't think it's necessary to have a Collection or Model since I'm only trying to implement routing at this time. Any help would be appreciated, thank you.

** EDIT **

I reordered the script imports to:

<script src="../underscore.js"></script>
<script src="../backbone.js"></script>
<script src="../jquery.js"></script>
<script src="../json2.js"></script>

and the error changed to TypeError: 'undefined' is not a function (evaluating 'Backbone.$(window)')

adding the breakpoint to line 1414 of backbone.js indicates the error is from evaluating this.checkUrl

checkUrl: function () { [native code] }
arguments: (...)
get arguments: function ThrowTypeError() { [native code] }
set arguments: function ThrowTypeError() { [native code] }
caller: (...)
get caller: function ThrowTypeError() { [native code] }
set caller: function ThrowTypeError() { [native code] }
length: 1
name: ""
__proto__: function Empty() {}
[[TargetFunction]]: function (e) {
[[BoundThis]]: Backbone.History
[[BoundArgs]]: Array[0]

the way I set up the router is de facto according to multiple sources, irrespective of the (function($){})(jQuery) and dunno how to get the path to be assigned correctly. using # did not help me.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
aug2uag
  • 3,379
  • 3
  • 32
  • 53
  • how about putting a breakpoint at that line in the code? – Stephen Thomas Apr 19 '14 at 21:33
  • backbone.js shows: Local{docMode:undefined, fragment:"", frame:undefined, loc:undefined, oldIE:null, options:undefined, this:Backbone.History{ _hasPushState:false, _wantsHashChange:true, _wantsPushState:false}} – aug2uag Apr 19 '14 at 21:42
  • tried passing options {pushState:true}, and defining `index: function() {}` in the `extend`, all aforementioned result with `Uncaught TypeError: undefined is not a function`, and couldn't find solution from previous post http://stackoverflow.com/questions/7343357/cannot-call-start-of-undefined-when-starting-backbone-js-history – aug2uag Apr 19 '14 at 21:55
  • Does your Backbone version have `Backbone.$`? Does your jQuery have `on`? – mu is too short Apr 19 '14 at 22:07
  • @muistooshort yes, as far as I can tell, created gist: https://gist.github.com/aug2uag/11099133 – aug2uag Apr 19 '14 at 22:11

1 Answers1

2

I notice two things in your code:

  1. The routes object is supposed to map route patterns to method names (or anonymous functions):

    The routes hash maps URLs with parameters to functions on your router (or just direct function definitions, if you prefer)

    but you don't have an index method defined in PageRouter.

  2. If you look at the route docs (or the Catalogue of Events), you will see that:

    The name argument will be triggered as a "route:name" event whenever the route is matched.

    So your router will trigger 'route:index' events, not 'index' events.

I can't reproduce the error you're seeing but if I address both of those points, things seem to be working as expected:

var PageRouter = Backbone.Router.extend({
    routes: {
        '': 'index'
    },
    index: function() {
        console.log('index');
    }
});
var pageRouter = new PageRouter();
pageRouter.on('route:index', function () {
    console.log('hey');
});
Backbone.history.start();

Demo: http://jsfiddle.net/ambiguous/kt7L8/

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • thank you for correcting my code, and indeed verifying that the source works for you, and the kind and generous response. there is the same issue that persists, and I am getting the same error, and only the error changes when I rearrange the order of importing source scripts. – aug2uag Apr 19 '14 at 23:06
  • Is there any chance that you can reproduce the problem at jsfiddle.net or jsbin.com? Might be easier to spot if I could see it happen. – mu is too short Apr 19 '14 at 23:13
  • yes, the file works on jsfiddle, can be seen at http://jsfiddle.net/aug2uag/cgwGr/ – aug2uag Apr 19 '14 at 23:29
  • believe it or not, code would not work for me with the js assets, and works fine with importing source from cdnjs. i dunno what, perhaps version mismatches, but sticking with cdnjs. Thanks for your help! – aug2uag Apr 19 '14 at 23:53
  • also, json2 was not necessary – aug2uag Apr 20 '14 at 00:09