ui-router: open state in new tab with target="_blank", params are lost
Asked Answered
V

2

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?

Vaginal answered 20/10, 2015 at 9:22 Comment(0)
A
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

Abbyabbye answered 20/10, 2015 at 11:13 Comment(5)
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.Vaginal
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?Gad
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.Vaginal
Well, there are techniques how to apply redirect. E.g. here https://mcmap.net/q/235218/-redirect-a-state-to-default-substate-with-ui-router-in-angularjs/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...Gad
Thank you for the linked question! Will definitely try this. Thank you for your time also!Vaginal
U
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>
Urrutia answered 21/12, 2016 at 7:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.