9

I'm doing an Angular app in which a table's rows has a button each, and on click of these buttons a new tab should be opened for the row that button is on.

I needed to pass parameters into the new tab created this way. I've declared the parameter in the state initialization:

.state('viewlisting', {
   url: "/listings/:id",
   params: {
     'action': '',
   },
   controller: 'ListingsController',
   templateUrl: "partials/listings/view_listing.html"
 });

and the button has something like this:

ui-sref='viewlisting({id:"+data+", action:"images"})'

The params are passed in, everything works as expected.

//URL: /#/listings/42
$state.params.action //returns "images"
$state.params.id //returns "42"

But adding target="_blank" to the <a> tag causes the $state.params object to return the following:

//URL: /#/listings/42
$state.params.action //returns ""
$state.params.id //returns "42"

I've searched for hours, I've looked at the ui-router documentation and the issue tracker for something that addresses my situation but I've found nothing.

Are state parameters not passed on target='_blank''ed ui-sref links?

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Ralph Sto. Domingo
  • 398
  • 1
  • 2
  • 13

2 Answers2

7

If there is any parameter which should be available outside of the current SPA context (new window, new tab) - it MUST be part of the url.

This will work:

.state('viewlisting', {
   // instead of this
   // url: "/listings/:id",
   // this will keep the action in a new window
   url: "/listings/:id?action",
   params: {
     'action': '',
   },
   controller: 'ListingsController',
   templateUrl: "partials/listings/view_listing.html"
 });

More details about params How to pass parameters using ui-sref in ui-router to controller

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thank you for this.. somehow I knew this was possible but I wanted to keep the action parameter from the URL. I just want to ask if there's a way where I can change the resulting url `/listings/42?action=images` to `listings/42`. – Ralph Sto. Domingo Oct 21 '15 at 00:41
  • The answer should be clear now (I mean after my answer) - NO it is not possible. URL is only way how to talk to extern world. And that is new tab, new window or just a link send via email. All needed params must be embeded into url. Is it clear now? – Radim Köhler Oct 22 '15 at 10:44
  • You've made that clear quite well, I was asking how to change the URL written on the address bar to `listings/42` AFTER `/listings/42?action=images`. It's not as if I'm rejecting your answer, I just don't want to expose the parameter to the user, so I was thinking if I could just the change the URL AFTER the page loads. – Ralph Sto. Domingo Oct 23 '15 at 04:32
  • Well, there are techniques how to apply redirect. E.g. here http://stackoverflow.com/q/29491079/1679310 *(so you can swallow the params in the second state...)* 1) user will be navigating to some state with url params 2) on state change this is taken, converted into $state.go and passed to other state, without url params. That could be the way... – Radim Köhler Oct 23 '15 at 04:39
  • Thank you for the linked question! Will definitely try this. Thank you for your time also! – Ralph Sto. Domingo Oct 23 '15 at 08:27
0

There is another way without using the URL. You can use LocalStorage instead of the URL.

Use ng-click on the link tag and call a function. In the function put your parameters in LocalStorage. Then in app.run use $rootScope.$on("$stateChangeStart") and check if LocalStorage have parameters. Then get params and call $state with params.

//in page controller: 
var openNewTab = function () {                  
                    localStorage.newTab = JSON.stringify({
                        state: "yourState",
                        params: {
                            param1: "someparam1",
                          param2:"someparam2"
                        }
                    });                  
                    window.open(document.location.origin);
                      
                }
 
 //angular app run config: 
angularApp.run(function($state){
if(localStorage.newTab){
   var newTab = JSON.parse(localStorage.newTab);
   localStorage.removeItem("newTab");
   $state.go(newTab.state, newTab.params);
   event.preventDefault();
}
})
<a ng-click="openNewTab()" >open new tab</a>
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
hamzeh.mm
  • 3
  • 5