0

I'm having an issue with "Backbone.history.start({ pushState: true}) " in require Js /Backbone Js / Marionette Js app, All of RequireJs dependencies are in their correct folders.

Here's is My issue: app is working perfectly without "pushState:true" parameter all require modules loaded as expected, but since without pushState parameter "#" shows in url hence to remove # from url i used Backbone.history.start({ pushState: true}). However , once I add {pushState: true} as a parameter to Backbone.history.start() in the top-level app.js file requireJs modules changes its loading path , and gives 404 (not found ) error and it unable to load require module entire code breaks down. so what is the issue with pushState? or how it works?

Here is my code App.js

define(['jquery', 'backbone', 'marionette', 'underscore', 'handlebars','init/configuration'],
function ($, Backbone, Marionette, _, Handlebars,config) {

     var MyApp = new Backbone.Marionette.Application();

    MyApp.addRegions({
         mainRegion:"#main"
    });

   MyApp.navigate = function(route,  options){
         options || (options = {});
        Backbone.history.navigate(route, options);
  };

    MyApp.getCurrentRoute = function(){
      return Backbone.history.fragment
  };
    MyApp.addInitializer(function () 
    {
        if(Backbone.history)
        {
        require(["js/app/routers/cmMessageRouter.js",], function () {
              Backbone.history.start({ pushState: true});

                if(MyApp.getCurrentRoute() === "")
                {
                    MyApp.trigger("show:message",7);    
                }
            }); 
      };     
    });
   return MyApp;
  });

cmMessageRouter.js

  define(["app"],function(app){

app.module("Message",function(message, app, Backbone, Marionette, $, _){

    message.router=Backbone.Marionette.AppRouter.extend({
        appRoutes : {
            "messages/:id":"showMessage"
        }
    });


    var API = {
          showMessage : function(id)
          {
                 require(["controllers/cmMessageController"], function(controller){
                     var controllerObj=new controller.messageController();
                     controllerObj.showMessage(id);
                });
          }
    };


    app.on("show:message",function(id){
            app.navigate("messages/"+id,{trigger: true});
    }); 

    app.addInitializer(function(){
        new message.router({
                 controller: API
         });
     });

   });
    return app.Message;
 });

cmMessageController.js

    define(["app","views/cmMessageView"],function(app,messageView){

app.module("Message.Controller",function(controller,app,Backbone,Marionette, $, _){

    controller.messageController = Backbone.Marionette.Controller.extend({

    //gets mapped to in AppRouter's appRoutes
      showMessage:function(userid) {
        require(["collections/cmMessageCollection","collections/cmContactCollection"], function(collection) {
             var contacts = app.request("contact:items");
             var model = contacts.get(userid);
             app.currentFriend=model.toJSON();

             var messageObj = new collection.messageCollection([] , {roomId : app.currentFriend.roomid});
             messageObj.getMessages(app.currentFriend.roomid, function(res){
                    if(res=="success")
                        API.renderMessageList();

             });
          });
       },

    });
 });
    return app.Message.Controller;
});

It gives following error in console GET ../messages/js/app/controllers/cmMessageController.js 404 (Not Found)

Actual path of CmMessageController is
../js/app/controllers/cmMessageController.js

how to tackle this issue? what m doing wrong??

sneha
  • 1
  • 1
  • You need to redirect all web requests to index.html, obviously excluding APIs if they are on the same server. Other than that your paths shouldn't break unless you did some very unexpectedly strange setup of requirejs. – Dominic Aug 05 '14 at 12:07

1 Answers1

0

If you want to use pushState feature, you should have your server response the same page for all of your routers. (yes, you should configure your server to use pushState).

For example, you have route "messages/:id":"showMessage".

Before you use pushState, if you wan view route messages/2, you will use url /index.html#messages/2, and browser will send request to GET /index.html, this is OK.

However, after use pushState, if you wan view route messages/2, you will use url /messages/2, and browser will send request to GET /messages/2, if you donot configure your server, server will return 404 error, because there no file /messages/2 in your folder! How to solve this problem ? You can explicitly congifure your server to response content of index.html when receive /messages/2 request. If you're using Nginx, you can refer Rewriting nginx for pushState-URL's.

Community
  • 1
  • 1
isayme
  • 309
  • 2
  • 11