Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router: Support Setting State Object When Navigating #10248

Closed
vsavkin opened this issue Jul 22, 2016 · 22 comments

Comments

Projects
None yet
@vsavkin
Copy link
Contributor

commented Jul 22, 2016

In addition to setting query params, we should be able to set the state object. See here:

https://developer.mozilla.org/en-US/docs/Web/API/History_API

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Dec 7, 2016

So what's the status on this? Will this be included in any of the upcoming releases?

@DzmitryShylovich

This comment has been minimized.

Copy link
Contributor

commented Dec 21, 2016

@stevenrobijns-macadam what is your use case?

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Dec 22, 2016

@DzmitryShylovich We want to supply data (for example an id or maybe a whole object) from one screen to another while navigating. BUT without needing to put that state in the URI.

So when navigating from api/order to api/orderline/orderLineId with router.navigate I for example want to supply the OrderId to the OrderLineComponent in a hidden manner, i don't want to see that OrderId reflected in that route.

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Dec 28, 2016

@DzmitryShylovich Did you see my reply?

@f-aubert

This comment has been minimized.

Copy link

commented Jul 3, 2017

Is there anything new? Passing an object to navigate methods, instead of having to stringify it as queryParams or save it in a Service, would be most valuable. Like others I cannot think of reasons where it would hurt to give front end developer this option.

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Jul 3, 2017

I'm still wondering as well.

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Jul 3, 2017

https://stackoverflow.com/questions/37157838/angular-2-passing-data-to-routes
@f-aubert check if Shubham Verma's comment please and keep us up-to-date if it works for you

@StevenLiekens

This comment has been minimized.

Copy link
Contributor

commented Jul 3, 2017

Guys, passing data via a service will obviously work but it is a cheap trick that comes with pitfalls.

The biggest pitfall is persistence. When you store router state in a shared service, you must write additional code to save that state to local storage (or whatever storage) and even more code to read the state from that storage when the application is restarted. Then you must start thinking about stale data. You probably don't want to keep route data around forever, do you? So you have to write code that cleans up route data when it's no longer needed. Turns out it's buggy so you promise your manager you'll fix it in the next release. So you fix it in between building other features and then you realize you must think about versioning the data because the new code is not compatible with the data that users have in their cache. Now is the time when you realize you're in hell and you wish you became a carpenter instead.

If you don't do all of this, your app will break if the user navigates to your routable component in a way that bypasses the procedure where you set the state, such as when the page is refreshed.

So let's not ever again bring up the suggestion that you can pass data via a service and instead let's start talking about how we can design the router to take advantage of state in the history API.

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Jul 3, 2017

@StevenLiekens: we're not really talking about saving state, that's a whole other issue.
The question is how we can get data from component a to component b. Let's say how can we pass an 'Order' object from the 'OrderComponent' to the 'OrderDetailComponent'. In this case, state should only be saved during the routing between 2 components. And not during application restarts.

@StevenLiekens

This comment has been minimized.

Copy link
Contributor

commented Jul 3, 2017

@stevenrobijns-macadam The thing is that with the history's pushState() API, that state is persisted automatically. That means that when you refresh the page or re-visit it from history, your component would be reloaded with the exact same state. You cannot get this behavior without writing a LOT of custom code if you use a shared service for passing state to a route.

In this case, state should only be saved during the routing between 2 components. And not during application restarts.

Application restarts are just one example of a way to navigate to a component directly. Other ways include using the Back/Forward browser buttons or pasting URLs into the address bar. All of these can potentially bypass code that passes the state from the master to the details component.

@f-aubert

This comment has been minimized.

Copy link

commented Jul 3, 2017

@stevenrobijns-macadam thanks for the link although it's not a solution for me as my use case would require to dynamically pass data. I know there are many ways of landing on a given route / component, but a common use case is the list of objects and then the object details. In my case this object is optional and would prepopulate the detail fields. As angular is after all mostly a one page application, there should be the possibility to pass data in memory for a specific routing resolution. As others said service could work but then we would have to manually clean such one time registered objects.

@stevenrobijns-macadam

This comment has been minimized.

Copy link

commented Jul 4, 2017

@f-aubert you're right, I didn't look into it much. This guy just proposes a solution for passing data(a string) dynamically in the url, which is not our question.

@sashanana

This comment has been minimized.

Copy link

commented Jul 27, 2017

Any update on this?

@RenaldasK

This comment has been minimized.

Copy link

commented Sep 8, 2017

+1

@saeedhomsy

This comment has been minimized.

Copy link

commented Oct 24, 2017

Is there any update

@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018

@StevenLiekens

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

This is still a huge pain to deal with. Shared services only get you so far. They are not a good substitute for history.state.

The best thing I could come up with is a service that controls navigation and also acts as resolve guard so that state is attached to every route snapshot. I haven't figured out a good way to also update the history API.

class StatefulNavigationService implements Resolve<any> {
  private state: any;
  
  constructor(private router: Router) {}
  
  navigateWithState(commands: any[], extras?: NavigationExtras, state?: any): Promise<boolean> {
    this.state = state;
    return this.router.navigate(commands, extras).then(success => {
        if (success) history.replaceState(this.state, null);
        this.state = null;
        return success;
    });
  }
  
  resolve(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): any {
    return this.state;
  }
}
@suraj021

This comment has been minimized.

Copy link

commented Aug 17, 2018

It's Aug'18, any update on this. This issue is pending from 2016.

@andreaslarssen

This comment has been minimized.

Copy link

commented Sep 5, 2018

+1

1 similar comment
@fredrik-macrobond

This comment has been minimized.

Copy link

commented Sep 6, 2018

+1

@Virendra-Yadav

This comment has been minimized.

@Virendra-Yadav

This comment has been minimized.

Copy link

commented Nov 14, 2018

@jasonaden

This comment has been minimized.

Copy link
Contributor

commented Dec 3, 2018

Closed by #27198

@jasonaden jasonaden closed this Dec 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.