Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I have ui-router go to an external link, such as google.com?

For example:

 $stateProvider
            .state('external', {
                url: 'http://www.google.com',

            })

url assumes that this is an internal state. I want it to be like href or something to that effect.

I have a navigation structure that will build from the ui-routes and I have a need for a link to go to an external link. Not necessarily just google, that's only an example.

Not looking for it in a link or as $state.href('http://www.google.com'). Need it declaratively in the routes config.

like image 927
Shane Avatar asked May 13 '15 16:05

Shane


5 Answers

Angular-ui-router doesn't support external URL, you need redirect the user using either $location.url() or $window.open()

I would suggest you to use $window.open('http://www.google.com', '_self') which will open URL on the same page.

Update

You can also customize ui-router by adding parameter external, it can be true/false.

  $stateProvider
  .state('external', {
       url: 'http://www.google.com',
       external: true
  })

Then configure $stateChangeStart in your state & handle redirection part there.

Run Block

myapp.run(function($rootScope, $window) {
  $rootScope.$on('$stateChangeStart',
    function(event, toState, toParams, fromState, fromParams) {
      if (toState.external) {
        event.preventDefault();
        $window.open(toState.url, '_self');
      }
    });
})

Sample Plunkr

Note: Open Plunkr in a new window in order to make it working, because google doesn't get open in iFrame due to some security reason.

like image 138
Pankaj Parkar Avatar answered Oct 23 '22 16:10

Pankaj Parkar


You could use the onEnter callback:

 $stateProvider
    .state('external', {
        onEnter: function($window) {
            $window.open('http://www.google.com', '_self');
        }
    });

Edit

Building on pankajparkar's answer, as I said I think you should avoid overriding an existing param name. ui-router put a great deal of effort to distinguish between states and url, so using both url and externalUrl could make sense...

So, I would implement an externalUrl param like so:

myApp.run(function($rootScope, $window) {
    $rootScope.$on(
        '$stateChangeStart',
        function(event, toState, toParams, fromState, fromParams) {
            if (toState.externalUrl) {
                event.preventDefault();
                $window.open(toState.externalUrl, '_self');
            }
        }
    );
});

And use it like so, with or without internal url:

$stateProvider.state('external', {
    // option url for sref
    // url: '/to-google',
    externalUrl: 'http://www.google.com'
});
like image 31
rixo Avatar answered Oct 23 '22 16:10

rixo


As mentioned in angular.js link behaviour - disable deep linking for specific URLs you need just to use

<a href="newlink" target="_self">link to external</a>

this will disable angularJS routing on a specific desired link.

like image 44
Ebrahim Avatar answered Oct 23 '22 17:10

Ebrahim


I transformed the accepted answer into one that assumes the latest version of AngularJS (currently 1.6), ui-router 1.x, Webpack 2 with Babel transpilation and the ng-annotate plugin for Babel.

.run(($transitions, $window) => {
  'ngInject'
  $transitions.onStart({
    to: (state) => state.external === true && state.url
  }, ($transition) => {
    const to = $transition.to()
    $window.open(to.url, to.target || '_self')
    return false
  })
})

And here's how the state may be configured:

.config(($stateProvider) => {
  'ngInject'
  $stateProvider
    .state({
      name: 'there',
      url:'https://google.com',
      external: true,
      target: '_blank'
    })
})

Usage:

<a ui-sref="there">To Google</a>
like image 1
Christiaan Westerbeek Avatar answered Oct 23 '22 18:10

Christiaan Westerbeek


The original answer is deprecated and disabled by default in UI Router, you may wish to explore implementing it using transition hooks

  .state("mystate", {
    externalUrl: 'https://google.com'
  })

then:

myApp.run(['$transitions', '$window', ($transitions, $window) => {
  $transitions.onEnter({}, function (transition) {
    const toState = transition.to();

    if (toState.externalUrl) {
      $window.open(toState.externalUrl, '_self');
      return false;
    }
    return true;
  });
}]
);
like image 1
vogomatix Avatar answered Oct 23 '22 17:10

vogomatix