Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs cordova base href

trying to set the correct base href value for an angularjs html5 web app to work in cordova

initially using $locationProvider.html5Mode(true) with <base href="/">:

  • app works perfectly in a normal browser
  • cordova gives resource errors for css / js / templates etc
    (I believe it looks for resources within the cordova root directory rather than the platform root?)

Tried a few alternatives are floated around here on SO and ui-router FAQs:

<base href="."> with html5 mode as per this answer :

  • assets are found ok in cordova (no resource errors)
  • ui-router goes into a tail-spin with infinite loop and the following error message
    Error: Failed to execute 'pushState' on 'History': A history state object with URL 'https://page/' cannot be created in a document with origin https://example.com

<base href="./"> with html5 mode:

  • assets found in cordova (no resource errors)
  • gives me the dreaded Error: 10 $digest() iterations reached. Aborting! message tried using frankwallis solution mentioned here but that didn't help (same error)

no base href with $locationProvider.html5Mode({enabled: true, requireBase: false});

  • assets found in cordova (no resource errors)
  • pages start loading inside themselves ?? ...like angular bootstraps twice in some states ?

my app config definition looks like:

myApp.config(['$locationProvider', '$urlRouterProvider', '$stateProvider', '$stickyStateProvider', function($locationProvider, $urlRouterProvider, $stateProvider, $stickyStateProvider) {

    $locationProvider.html5Mode(true);

    $stateProvider
    .state('root', {            // we define a 'root' state so that we can load some essential data prior to any template being loaded
        url: '',
        abstract: true,
        sticky: true,
        views: {
            'root': {
                template: '<ui-view/>',
            }
        }
    })
    .state('root.worldmap', {
        url : '/worldmap',
        templateUrl : 'templates/worldmap.tmpl.html'
    })
    .state('root.faq', {
        url : '/faq',
        templateUrl : 'templates/faq.tmpl.html'
    })
    .state("otherwise", {
        url: "*path",
        views: {
            'root': {
                template: "",
                controller: ['$injector', function($injector) {
                    var $state = $injector.get("$state");
                    $state.go('root.worldmap');
                }]
            }
        },
    });
    $stickyStateProvider.enableDebug(true);
}]);

For info: using this method of alternative cordova deviceready vs angular.element bootstrap for cordova / browser respectively

like image 347
goredwards Avatar asked Nov 18 '16 08:11

goredwards


1 Answers

OK so the way to get this working is by removing the base href AND disabling html5 mode :

  • [optional] create & checkout a new branch called dev-cordova or similar
    • this allows you to switch quickly between browser and device code
  • delete / comment the <base href="/"> in the main index.html
  • ensure that html5 mode is disabled in app.js by either

    $locationProvider.html5Mode({
        enabled: false,
        requireBase: false
    });
    

    or

    $locationProvider.html5Mode(false);
    

Don't forget to run cordova build ios (after you grunt / gulp etc to compile the js files)
...this ensures the files in the cordova /platforms/ios/www directory are updated.

like image 83
goredwards Avatar answered Nov 13 '22 19:11

goredwards