0

I am building an application with the fiddle here for self teaching with Backbone and node.js express and mongodb.

I have a problem with constructing the Router I have defined by extending from Backbone.Router.

In js console I have the error messages:

[Error] TypeError: undefined is not a function (evaluating 'n.replace')
    template (underscore-min.js, line 5)
    global code (app.js, line 17)
[Error] TypeError: undefined is not a constructor (evaluating 'new appRouter()')
    (anonymous function) (localhost, line 79)
    j (jquery.min.js, line 2)
    fireWith (jquery.min.js, line 2)
    ready (jquery.min.js, line 2)
    I (jquery.min.js, line 2)
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (jquery.min.map, line 0)
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (backbone-min.map, line 0)
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (underscore-min.map, line 0)

As I have checked I do not have any syntactic error. Is my Entry Point Script not ensured to be executed after the app.js is loaded by the jQuery .ready() alias I use?

What is ht thing I am missing here?

public/app.js

    _.templateSettings = {
     interpolate: /\{\{(.+?)\}\}/g
};
//Define Models, Collections, Views 
var postModel = Backbone.Model.extend({

});

var postsCollection = Backbone.Collection.extend({
    model: postModel,
    url: "/posts"
});

var postsListView = Backbone.View.extend({
    main: $('body'),
    collection: postsCollection,//! May be collection must be created to use in view.
    template1: _.template( $('#postsListTemplate') ),
    template2: _.template( $('#postsListItemTemplate') ),

    initialize: function(){
        this.render();
        this.collection = new postsCollection();
        this.collection.fetch();
        this.collection.on('add', this.renderPostsListItem, this);
    },

    render: function(){
        this.main.html( this.template1() );
        return this;
    },

    renderPostsListItem: function(){
        this.collection.forEach(function(each){
            this.$el.append( this.template2(each) );
        });
        return this;
    }
});


//Define Client-Side Routes
var appRouter = Backbone.Router.extend({
    routes: {
        "": "viewPosts",
    },

    viewPosts: function(){
        this.postslistview = new postsListView();
    },
});

views/index.ejs

<html>
    <head>
    <!--Templates-->

        <!--Post Templates-->
        <script type="text/template" id="postsListTemplate">
            <h1>Blog</h1>
            <h2>All Posts</h2>

            <ul></ul>
        </script>

        <script type="text/template" id="postsListItemTemplate">
            <li>{{title}}</li>
        </script>

        <script type="text/template" id="postTemplate">
            <a href="/">All Posts</a>

            <h3>{{title}}</h3>
            <p>{{pubDate}}</p>
            <p>{{content}}</p>

            <a href="/posts/:id/comments">Comments</a>
        </script>

        <script type="text/template" id="postFormTemplate">
            <form>
                <input id="name" type="text"></input>
                <input id="title" type="text"></input>
                <textarea id="content"></textarea>
                <button id="postpost"></button>
            </form>
        </script>

        <!--Comment Templates-->

        <script type="text/template" id="commentsListTemplate">
            <a href="/">All Posts</a>
            <a href"/posts/:id">Post</a>

            <h1>Comments</h1>

            <ul></ul>
        </script>

        <script type="text/template" id="commentsListItemTemplate">
            <li>
                <p>{{name}}</p>
                <p>{{pubDate}}</p>
                <p>{{content}}</p>
            </li>
        </script>

        <script type="text/template" id="commentFormTemplate">
            <form>
                <input id="name" type="text"></input>
                <textarea id="content"></textarea>
                <button id="postcomment"></button>
            </form>
        </script>

    <!--Linked Files: Libs & Scripts-->

        <script src="jquery.min.js"></script>
        <script src="underscore-min.js"></script>
        <script src="backbone-min.js"></script>
        <script src="app.js"></script>


    </head>

    <body>

    <!--Entry Point Scripts-->
        <!--Router can be-->
        <script>
            $(document).ready(function(){
                var approuter = new appRouter();
                Backbone.history.start({pushState: true});
            });     
        </script>
    </body>
</html>

server.js

//Require Modules
var express = require('express');
var waterline = require('waterline');
var sailsMongo = require('sails-mongo');
var path = require('path');
var serveStatic = require('serve-static');
var bodyParser = require('body-parser')

//Create Objects of Required Modules
    //Probably Https server, db Conenction
var app = express();
var orm = new waterline();

//Configs, Middlewares for Created Objects of Modules.
    //Dir to serve static assets; css, js, index.
    //Body parser; json, urlencoded
    //Config-object for Waterline.
app.use( serveStatic( path.join(__dirname, 'public') ) );
app.use(bodyParser.json());

var ormConfig = {
    adapters: {
        mongodbAdapter: sailsMongo
    },
    connections: {
        mongodbConnection: {
            adapter: 'mongodbAdapter',
            host: 'localhost',
            database: 'Blog',
            //port:,
            //user:,
            //password:,
        }
    }
};

//Define Db Schemae, Models
    //Define Models
    //Load Defined Models into ORM
var postModel = waterline.Collection.extend({
  identity: 'posts',
  connection: 'mongodbConnection',

  attributes: {
      title: 'string',
      author: {type: 'string', required: true},
      body:   'string',
      comments: [{ body: 'string', date: 'date' }],
      date: { type: 'date', default: Date.now, required: true },
      hidden: 'boolean',
      meta: {
        votes: 'integer',
        favs:  'integer'
      }
  }
});
orm.loadCollection(postModel);

//Init Created and Configured Objects of Modules
    //Init ORM. Init express server.
orm.initialize(ormConfig, function(err, models) {
    if(err) throw err;

    //! NOT MUST CODE. JUST TO ABBREVIATE
    app.models = models.collections;
    app.connections = models.connections;
});

app.listen(3333);

//Define Routes
app.get('/', function(req, res){
    res.render('index.ejs');
});
Travis Webb
  • 14,688
  • 7
  • 55
  • 109
sçuçu
  • 2,960
  • 2
  • 33
  • 60
  • I have realised that in my template attributes I do not pass the html of the objects I have selected by jQuery by making `template: _.template( $('#someTemplate').html() )`. I did it and now I do not have the first two errors. But a different one and I know why of it is I dşd not defined sereverside route of it, the '/posts', the location of the collection on the server. Problem solved. But still cannot understand why it gives such an error message and cannot lead me to it directly. – sçuçu Dec 07 '14 at 21:46
  • Looks like you don't have a 'posts' route defined, so jsut defined it and handle it – Vsevolod Goloviznin Dec 07 '14 at 21:48
  • yes. as I stated in the comment I know it now. But why it gave previous errors about router and while only I have a missing .html() for templates, although it gave the underscore error but it either doesn't seem to the point. – sçuçu Dec 07 '14 at 21:50

1 Answers1

0

Underscore function _.template() expects html, so, .html() method should be used on an element selected by the DOM selector, jQuery, to take the selected Object's html when assigning;

template1: _.template( $('#postsListTemplate') ),

just as following;

template1: _.template( $('#postsListTemplate').html() ),.

sçuçu
  • 2,960
  • 2
  • 33
  • 60