1

I am trying to overwrite portions of my single page app using only javascript and AngularJS.

Overwrites are based on subdomain.

Every subdomain is pointing to the same doc root.

controllers.js

controller('AppController', ['$scope','$route','$routeParams','$location', function($scope, $route, $routeParams, $location) {    
  $scope.$on("$routeChangeSuccess",function( $currentRoute, $previousRoute ){
    render();
  });
  var render = function(){
    //Is it actually a subdomain?
    if($location.host().split(".",1).length>2){ 
      //Use subdomain folder if it is.
      var url = "views/"+$location.host().split(".",1)+"/"+$route.current.template;
      var http = new XMLHttpRequest();    
      http.onreadystatechange=function(){
        if (http.readyState==4){
          //If there isn't an overwrite, use the original.
          $scope.page = (http.status!=404)?url:("views/"+$route.current.template);
        }
      }
      http.open('HEAD', url, true);
      http.send();
    }
    else{
      //Else we are on the parent domain.
      $scope.page  = "views/"+$route.current.template;
    }
  };
}])

config.js

config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider.when('/', {
    template: 'home.html'
  });
  $routeProvider.when('/services', {
    template: 'services.html'
  });
  $routeProvider.otherwise({redirectTo: '/'});
}]);

index.html

<html lang="en" ng-app="myApp" ng-controller="AppController">
<body>
<div ng-include src="page" class="container"></div>
</body>
</html>

Because this is a single page app, when you hit a URL directly, it's going to 404. That's why we apply rewrite rules on the server. In my case I'm using nginx:

location / {
   try_files $uri /index.html;
}

This works great when I'm not on a subdomain, but then again I'm also not sending out an XMLHttpRequest. When I do use the subdomain, now we need to check for an overwrite.

The tricky part here is that the rewrite rules are forcing the XMLHttpRequest to return a 200.

Ideas on how I can have my cake and eat it too?

1
  • first thing to point out dont use XMLHttpRequest directly just use $http provided by angular meanwhile i check the problem Commented Jun 13, 2013 at 20:14

1 Answer 1

1

I decided to go with a local stradegy for two reasons:

  1. There is no additional overhead of XML request.
  2. 404 messages wont polute console logs when resource doesn't exist.

services.js

factory('Views', function($location,$route,$routeParams,objExistsFilter) {

  var viewsService = {};
  var views = {
    subdomain1:{
      'home.html':'/views/subdomain1/home.html'
      },
    subdomain2:{

    },
    'home.html':'/views/home.html',
  };

  viewsService.returnView = function() {
    var y = $route.current.template;
    var x = $location.host().split(".");
    return (x.length>2)?(objExistsFilter(views[x[0]][y]))?views[x[0]][y]:views[y]:views[y];
  };

  viewsService.returnViews = function() {
    return views;
  };

  return viewsService;
}).

controllers.js

controller('AppController', ['$scope','Views', function($scope, Views) {    
  $scope.$on("$routeChangeSuccess",function( $currentRoute, $previousRoute ){
    $scope.page = Views.returnView();
  });
}]).

filters.js

filter('objExists', function () {
  return function (property) {
    try {
      return property;
    } catch (err) {
      return null
    }
  };
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.