2

I am using ui-router for state navigation in angular application and in one of the scenario I have to navigate to a new state in an different tab.

I have the following state

.state("code",
        {
            url: "/code",
            params: { offer : null },
            templateUrl: "app/components/coupons/views/code.html"
        })

offer in param is an object. When navigating to this state in the same browser it works fine. But when navigating to this state in a different browser offer comes as null.

The same question was posted by another user here http://stackoverflow.hex1.ru/questions/33232761/ui-router-open-state-in-new-tab-with-target-blank-params-are-lost but here the param is a property and not an object. So, it could be added to url.

Thanks, Sam

Sumesh Kuttan
  • 1,333
  • 1
  • 17
  • 40

4 Answers4

1

When you open a new tab, a new instance of your app is created in the new tab because it's based on javascript and it will not hold its parameters when the page is fresh. So your state loads with a null parameter because this page has no relation to the other page you had. As a workaround, I suggest you attach your data to $window and retrieve it on the new page.

Sina Gh
  • 598
  • 3
  • 8
  • looks like the last thing i might want to try out. But definitely I will keep this option. Lets see if someone can come up with a cleaner way. Else I will do this way and mark this as answer – Sumesh Kuttan Jan 10 '16 at 09:35
  • The options I have played around with are local storage, $window and cookies. I didn't want to have to delete data from local storage so I passed on that option, and the purpose of cookies isn't to pass along data in an app so I also passed on that, and used the good old `$window`. – Sina Gh Jan 10 '16 at 10:04
1

I have done it in typescript and it works:

var myWindow=this.$window;
var myData={data:'testData'};
myWindow.localStorage.myData=JSON.stringify(myData);
window.open(this.state.href('state', {}, {absolute: false, inherit: true}));

Then in the new tab Controller:

var myWindow=this.$window;
var myData=JSON.parse(myWindow.localStorage.myData);
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
Maganjo
  • 59
  • 2
1

The correct way to deliver a state to a new tab is through the URL

I suggest the following steps:

  1. Instead of using the params property, add your parameter to the URL
    (in your example, change the url property in the state definition to: url: "/code?offer",)
  2. Before calling $state.href() with the offer object - convert it to a string using JSON.stringify(offer)
  3. In the receiving end, convert the param back using JSON.parse(offer)

Simple and clean.

As for the localStorage solution that other people suggested - it will have the following issues:

  1. If the user opens several tabs, their localStorage state will be overwritten by each other. If this happens fast enough or the application takes enough time to load - the user will be presented with multiple tabs all with the content of the last link they clicked.
  2. The user can't bookmark the newly opened tab or even refresh it without losing the state, making the page unusable.
lilotop
  • 527
  • 6
  • 12
0

The clean way would be to not open a new browser tab. As said by sina a new instance of your angular app is created. That means all state that might be hold in services is lost. Can't think of a other possibilities:

  1. Put relevant info in the url
  2. I don't think that you can share information with $window but you could use localStorage
  3. Cookies would also be a valid options

Javascript: sharing data between tabs

Community
  • 1
  • 1
ChrisY
  • 1,681
  • 10
  • 12
  • `var myWindow = $window.open("url"); myWindow.data = $scope.dataToBePassedAlong;` ... This can pass along data when you open a new window using $window, and then on the new page you can easily retrieve it from `$window.data`. – Sina Gh Jan 10 '16 at 10:03
  • i might probably send some ids in the url and get the object from REST in the new state's controller. It would have been a good option not to have it this way as I already have the whole object in my previous state. – Sumesh Kuttan Jan 10 '16 at 10:12
  • @sina: have you done this already? According to this: https://books.google.at/books?id=4RChxt67lvwC&pg=PA353&lpg=PA353&dq=when+is+a+window+object+created+javascript+browser+tabs&source=bl&ots=th_3DhFUn9&sig=kaRMdu20XR1-YmCYulMDWVK_hiY&hl=de&sa=X&ved=0ahUKEwit4d2HgJ_KAhVGxRQKHRdXBLUQ6AEIUTAG#v=onepage&q=when%20is%20a%20window%20object%20created%20javascript%20browser%20tabs&f=false using `_blank` always gives a new window object. – ChrisY Jan 10 '16 at 10:19
  • I have done it with the code I wrote in my previous comment, so I've done it using the `$window` object to open a new window, not just a normal link with _blank because I couldn't attach data to it :) – Sina Gh Jan 10 '16 at 11:00