Category Archives: angular-ui-router

AngularJS HTML5 mode with UI Router on apache

I had turned on the html 5 mode on my angular(1.5.8) app a few days back with this code:

$locationProvider.html5Mode({enabled:true,requireBase:true}).hashPrefix('!');

Later I read configuring apache server for html5 mode with ui-router.

After doing these settings, I am facing 2 problems:

  1. Browser reload, redirects to home page for every deep nested app link.
  2. Any link coming from outside(via email) always redirects to the homepage.

I have played with

  1. mod_rewrite as-in using <Directory>, FallbackResource on apache.
  2. changing paths to assets in the index.html (using relative URI and full qualified URI)
  3. adding/removing the base HTML tag. (trying options like '/', '<sitename>')

But I am yet to overcome these problems.

Here is the detailed setup on my localhost:

  1. I am deploying to apache via Virtual Host(and not .htaccess).
  2. My deployment directory is /Users/<name>/Sites/<sitename> (I am on mac OS)
  3. My index.html in-parts is as follows:

        <head>
          <base href="/">
          <!-- SPELLS 1-->
            <script src="/js/jquery.min.js"></script>
            <script src="/js/bootstrap.min.js"></script>
            <script src="/js/angular.min.js"></script>
            <!-- more scripts / css et al -->
        </head>
    
  4. My Apache(2.4.28) config is as follows:

        <VirtualHost *:80>
        ServerName <servername>
        DocumentRoot "/Users/<name>/Sites/<sitename>"
        #LogLevel debug
        LogLevel debug rewrite:trace6
        RewriteEngine on
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
        RewriteRule ^ - [L]
        RewriteRule ^ index.html [L]
    
        Options Indexes FollowSymLinks
        Require all granted
    
        </VirtualHost>
    

Can anyone help me with the exact setup?

htaccess redirect angular refresh redirecting to home page

In my angularJS application i have removed # by using html5Mode and base tag. Like following:

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

    $locationProvider.html5Mode(true);
    $stateProvider
        .state('main', {
            views: {
                "myWidget": {
                    template: "<div ui-view='my_nested_view' id='my_nested_view'> <div/>",
                    controller: myWidgetCtrl
                }
            }
        })
        .state('main.testPage', {
            url: '/testpage',
            views: {
                "[email protected]" : {
                    template: testPageTemplate,
                    controllerAs: 'testPageCtrl',
                    controller: testPageCtrl
                }
            }
        });
    }
]);

In index.html i have <base href="/"> in head section. So i am able to remove # from url. When open localhost which is running on Apache and nevigate to different pages like /demo by clicking link it works well. But when i refresh it gives me 404 page not found error.

So i got .htaccess to achieve requirement that page should load after pressing F5 also means reload also.

RewriteEngine On  
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html 

But problem is this when i reload after using this htaccess it redirects to home page. Like if i navigate by clicking on localhost/testpage it works perfectly but once it hit same url localhost/testpage it redirect back to localhost.

ui-router and htaccess for Angular 1(sub url not refreshing)

I can't get the sub url to work when refresh the sub url or go straight to it. Here is my config for ui-router:

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

  $urlRouterProvider.otherwise('/');
  $urlRouterProvider.when('','/home'

);
      $locationProvider.html5Mode(true);

  $stateProvider
  .state('home',{
    url:'/',
    templateUrl:'templates/home.htm',
  })
  .state('services',{
    url:'/services', //What the url link will show
    templateUrl:'templates/services.htm',
    controller: 'servicesCtrl'
  });
$locationProvider.html5Mode(true);
}]);

Changed httpd.conf:

<Directory "/Library/WebServer/Documents">
    Options FollowSymLinks Multiviews
    MultiviewsMatch Any
    AllowOverride All
    Require all granted
</Directory>

My .htaccess file:

RewriteEngine on #engine begin
RewriteCond %{REQUEST_FILENAME} -f [OR] #find file
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /index.html [NC,L]

ErrorDocument 404 /error/404.html

I am not too familiar with htaccess, but that is the setting I used for my previous project and it worked. Please advise.

how to make url with dynamic username in angular 1?

I am new to angularJs (version 1), I am trying to write a route for my application using ui-router.

My application opens on the browser using the below link:

http://localhost:8000/ that is converted to http://localhost:8000/#/

There are some other links like http://localhost:8000/#/contactus and http://localhost:8000/#/posts etc.

Problem is:

http://localhost:8000/#/

fetches a user's data from remote. currently, I have hardcoded the username to get the details.

I want to make it dynamic by passing the username in the url like as follows:

http://localhost:8000/{myName}/

Example:

http://localhost:8000/jack

Please suggest, how should I write the route (using ui-router state). I don't want to change the urls.

Should I create .htaccess file to rewrite the url or is it possible in angular somehow?

$stateProvider
        .state('main', {
            views: {
                "myWidget": {
                    template: "<div ui-view='my_nested_view' id='my_nested_view'> <div/>",
                    controller: myWidgetCtrl
                }
            }
        })
        .state('main.contactus', {
            url: '/contactus',
            views: {
                "[email protected]" : {
                    template: 'contactus.html',
                    controllerAs: 'contactusCtrl',
                    controller: contactusController
                }
            }
        })
        .state('main.posts', {
            url: '/posts',
            views: {
                "[email protected]" : {
                    template: postsTemplate,
                    controllerAs: 'postsCtrl',
                    controller: postsController
                }
            }
        });

I want to allow the user to pass his username in the url.

For example

localhost:8000/ it opens the home page that is correct.

localhost:8000/stackg91 currently give not found error. I want to allow the user to pass username in the url, Instead of giving error it should open the home page.

base url: http://localhost:8082/#/

want to pass http://localhost:8082/dinesh/#/

Angular ui-routing with domain aliases

We use Angular-UI-Router to navigate to our website. That is working fine. But we want to use domain aliases which point to a specific page of the website, with the url of the alias in the addressbar.

Example: We have the website: domain.com with some shop pages. domain.com/shop/shop-name, shop/shop-2, shop/store-name, etc. We want to have multiple domainnames with a alias to the /shop/[shop-slug] pages.

The site itselfs runs with NodeJS, but somebody created a setup with apache and NodeJS, so we can create aliasses in Apache, which redirects to the specified page. This is an example for a redirect:

VirtualHost file

<VirtualHost *:80>
  ServerName domainalias.com
  RewriteEngine on
  RewriteRule ^ https://domainalias.com/ [R]
</VirtualHost>

<VirtualHost *:443>
  ServerName domainalias.com
  RewriteEngine on
  RewriteRule ^/$ http://127.0.0.1:3000/shop/demo1 [P]
  RewriteRule ^/(.+) http://127.0.0.1:3000/$1 [P]
  Include /etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile [certfile]
  SSLCertificateKeyFile [certfile]
  SSLCertificateChainFile [certfile]
</VirtualHost> 

That works fine, but, the url is showing in the address bar like: domainalias.com/shop/demo1/

We think that the UI-router is doing a redirect with a new URL. Currently our routings file is:

Ui-Router

app.config(['$locationProvider', '$sceProvider', '$stateProvider', '$urlMatcherFactoryProvider', '$urlRouterProvider',
function($locationProvider, $sceProvider, $stateProvider, $urlMatcherFactoryProvider, $urlRouterProvider) {

    // disabled due some other problems with the redirects to the shop pages
    // but can't refresh a page now > other problem
    // $urlMatcherFactoryProvider.strictMode(false);

    // $urlRouterProvider.rule(function($injector, $location) {
    //  var path = $location.path();
    //  var hasTrailingSlash = path[path.length-1] === '/';

    //  if(hasTrailingSlash) {
    //      //if last charcter is a slash, return the same url without the slash  
    //      var newPath = path.substr(0, path.length - 1); 
    //      return newPath;
    //  }
    // });

    $urlRouterProvider
        // Show homepage by default on the shop/pro-shop.
        .when('/shop/:nameSlug/', '/shop/:nameSlug/home')

        // Redirect invalid routes to homepage.
        .otherwise('/home');

    $stateProvider

        .state('shop', {
            abstract: true,
            url: '/shop/:nameSlug',
            templateUrl: '/views/shop/index.html',
            controller: 'shopController',

        })

            .state('shop.home', {
                url: '/home',
                templateUrl: '/views/shop/home.html'
            })

            .state('shop.product', {
                url: '/products/:productNameSlug',
                templateUrl: '/views/product.html',
                controller: 'productController'
            })

            .state('shop.products', {
                url: '/products',
                templateUrl: '/views/products.html'
            })

            .state('shop.brand', {
                url: '/brands/:brandNameSlug',
                templateUrl: '/views/brand.html',
                controller: 'brandController'
            })

            .state('shop.brands', {
                url: '/brands',
                templateUrl: '/views/brands.html'
            })

            .state('shop.campaigns', {
                url: '/campaigns',
                templateUrl: '/views/campaigns.html'
            })

            .state('shop.campaign', {
                url: '/campaigns/:campaignNameSlug',
                templateUrl: '/views/campaign.html',
                controller: 'campaignController'
            })

            .state('shop.contact', {
                url: '/contact',
                templateUrl: '/views/shop/contact.html'
            })

            .state('shop.custom-page', {
                url: '/:customPageNameSlug',
                templateUrl: '/views/shop/custom-page.html'
            })

            .state('shop.cart', {
                url: '/cart',
                templateUrl: '/views/cart.html',
                controller: 'checkoutController'
            })

        .state('layout', {
            abstract: true,
            templateUrl: '/views/layout.html',
            controller: 'homeController'
        })

            .state('layout.home', {
                url: '/home',
                templateUrl: '/views/home.html',
                controller: 'homeController'
            })

            .state('layout.product', {
                url: '/products/:nameSlug',
                templateUrl: '/views/product.html',
                controller: 'productController'
            })

            .state('layout.products', {
                url: '/products',
                templateUrl: '/views/products.html',
                controller: 'productsController',
                data: {
                    pageTitle: 'Producten'
                }
            })

            .state('layout.brand', {
                url: '/brands/:nameSlug',
                templateUrl: '/views/brand.html',
                controller: 'brandController'
            })

            .state('layout.brands', {
                url: '/brands',
                templateUrl: '/views/brands.html',
                controller: 'brandsController'
            })

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

As you can see, we comment out some lines above the routings to make the redirects possible, with this code on, alle the pages of a alias are redirected to /home.

Question:

Is it possible to make a shop page available under a domain alias? So we get URL's like domainalias.com/home and domainalias.com/products and not domainalias.com/shop/demo1/home and domainalias.com/shop/demo1/products and is it possible to fix the refresh page? With the code commented out, every refresh is doing a redirect to /home also.

EDIT With a curl to domainalias.com we see a 301 redirect to /shop/demo1

HTTP/1.1 301 Moved Permanently
Date: Thu, 02 Feb 2017 11:02:01 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: Express
Content-Type: text/html; charset=UTF-8
Content-Length: 55
X-Content-Type-Options: nosniff
Location: /shop/demo1/
Vary: Accept-Encoding

But, we can't find this redirect. We haven't created it, and since it is 'Powered-By: Express' it must be on the NodeJS server

404 error in Google Webmaster tools using Angular UI Router

I get a 404 error when I am using Google Webmaster Tools to fetch a page. It happens to all pages except the root "/". I also get the 404 error with prerender io. However when I surf the page manually I see the page normally.

I am using Angular UI Router. with HTML5Mode on and also added this to the head.

<base href="/">
<meta name="fragment" content="!">

And in .htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]
    RewriteRule ^ /index.php
</IfModule>

Apache doesn’t detect ui-router state change

I am using LocationMatch Apache directive to apply some logic to an AngularJS app. To test, I have the regex cover just one state, http://my.ui.com/login

Apache

<LocationMatch "^/(login)(.*)">
    Redirect "/login" "/login2"
</LocationMatch>

This simple Redirect is used to check if the block has been triggered. When I got to the URL above directly (fake URL, sorry I can't share the real app), I can see the redirect working by observing the URL bar. However, if I navigate to this state using a ui-sref button, the LocationMatch block is never triggered. Here is the relevant AngularJS code, I am using the ui-router library:

UI State

$stateProvider.state('login', {
    url: '/login',
    templateUrl: 'login.html',
    controller: 'LoginCtrl'
});

Button (clicking doesn't trigger Apache)

<button class="md-button" ui-sref="login">Login</button>

I'm guessing because the AngularJS app is loaded all at once, there is no disk read made when a stateChange occurs. Does anyone know of a better way for Apache to detect state changes in an AngularJS app?

AngularJS pretty URLs does work only partialy

I have a problem with AngularJS ui-routing, for some reason the routing works only partialy when I want to use "pretty URLs", I looked up many tutorials and threads on these forums, but I just can't find any solution for this.

I have an app just like this one: https://scotch.io/tutorials/angular-routing-using-ui-router, the only change I made is, that I added <base href="/"> in <head> of index.html file.

By default it works fine, but in the url there is always hastag so the url looks like

http://ag-routing.lc/#/home

but I want it to look like this

http://ag-routing.lc/home

before you start downvoting me that this is a duplicate, here comes the problem:

On every forum I looked at, this is supposed to be the solution, paste it in your config and magic will happen.

$locationProvider.html5Mode(true);

This is how my app.js looks like with the hasbang code

// app.js
var routerApp = angular.module('routerApp', ['ui.router']);

routerApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

$locationProvider.html5Mode(true);

$urlRouterProvider.otherwise('/home');

$stateProvider

// HOME STATES AND NESTED VIEWS ========================================
    .state('home', {
        url: '/home',
        templateUrl: 'partial-home.html'
    })
......

Now the # is gone, but if I refresh the page, I get a weird results or 404. So again I looked up for a solution and found out, that you have to add this code to .htaccess (source)

RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]

Yay, now it works with refresh and direct links as well, but here is the real problem for which I can't find a solution:

When I hit refresh on page

http://ag-routing.lc/home

It works fine, but when I go directly (or by refresh) on page

http://ag-routing.lc/home/paragraph

it breaks, simply, second "/" will just nuke the page from orbit, it stops working and I have no idea why, the only thing I found out is, that when I open the console in chrome I get really weird results such as:

app.js:3 Uncaught SyntaxError: Unexpected token <
angular.js:3660 Uncaught Error: [$injector:modulerr] Failed to instantiate   module routerApp due to:
Error: [$injector:nomod] Module 'routerApp' is not available! You either  misspelled the module name or forgot to load it. If registering a module ensure  that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.2.13/$injector/nomod?p0=routerApp
at https://code.angularjs.org/1.2.13/angular.js:78:12
at https://code.angularjs.org/1.2.13/angular.js:1531:17
at ensure (https://code.angularjs.org/1.2.13/angular.js:1456:38)
at module (https://code.angularjs.org/1.2.13/angular.js:1529:14)
at https://code.angularjs.org/1.2.13/angular.js:3632:22
at Array.forEach (native)
at forEach (https://code.angularjs.org/1.2.13/angular.js:304:11)
at loadModules (https://code.angularjs.org/1.2.13/angular.js:3626:5)
at createInjector (https://code.angularjs.org/1.2.13/angular.js:3566:11)
at doBootstrap (https://code.angularjs.org/1.2.13/angular.js:1301:20)
http://errors.angularjs.org/1.2.13/$injector/modulerr?p0=routerApp&p1=Error…trap%20(https%3A%2F%2Fcode.angularjs.org%2F1.2.13%2Fangular.js%3A1301%3A20)

and the biggest mindblown is, that when I open app.js in resources, the js code is gone and it's replaced with the HTML from index.html ಠ_ಠ

Any help appreciated and sorry for bad English...

By the way, the problem persists when I use ng-route instead of ui-route.

EDIT: I found out that when I set the locationProvider to false and hit refresh, the url turns into this thing, which seems to be wrong:

http://ag-routing.lc/about#/about

url not working using ui-route when I type in the url or google search the url

I am using ui-router to route my template contents to my index in a single page application. The route works if I go to my site's index page first then navigate to different content. But if I type in the url like http://www.domain.com/contact, it gave me a 404.
Here is my my app.js with the ui-route

var app = angular.module('app',['ui.router','vAccordion']);

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

  $urlRouterProvider.otherwise('/');
  $urlRouterProvider.when('','/home');

  $stateProvider
  .state('home',{
    url:'/',
    templateUrl:'templates/home.html',
  })
  .state('history',{
    url:'/history', //What the url link will show
    templateUrl:'templates/history.html',
  })
  .state('ensembles',{
    url:'/ensembles',
    templateUrl:'templates/ensembles.html'
  })
  .state('staffs',{
    url:'/staffs',
    templateUrl:'templates/staffs.html'
  })
  .state('career',{
    url:'/career',
    templateUrl:'templates/career.html'
  })
  .state('contact',{
    url:'/contact',
    templateUrl:'templates/contact.html'
  });

My .htaccess file:

Redirect /history/ /#/history
Redirect /ensembles/ /#/ensembles
Redirect /staffs/ /#/staffs
Redirect /career/ /#/career
Redirect /contact/ /#/contact

ErrorDocument 404 /index

I want to type in "www.domain.com/contact" and render the contact template in the index view.

Safari Angular URL Parameters being ignored when redirected from a server-side API

My application is using a server-side API that redirects users to an Angular URL in this form:

https://www.myapp.com/#/app?someKey=value1&someKey2=value2

When I test on Chrome, Firefox, and IE, everything works well. When I test on Safari, the browser ignores everything after the # and redirects to this instead:

https://www.myapp.com/

... as if it was ignoring the hashbang. I played around with encoding the hashtag to %23, but Safari then complains 404 (as expected, since myapp.com/%23/app isn't really a directory on my web server).

I've googled around and the closest issue I've found was this: Url parameters work on Chrome, Firefox but not on Safari

And no other reports. Due to the lack of actual reports, I'm going to assume this is either an unknown Safari bug, or I'm doing something wrong.

Could anyone advise?