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

transition to another state. #64

Closed
roger-king opened this issue Jul 16, 2017 · 7 comments
Closed

transition to another state. #64

roger-king opened this issue Jul 16, 2017 · 7 comments

Comments

@roger-king
Copy link

With React being very very component based. How do I transition from one state to another?

I am seeing calling transition.router.stateService.target or .go but that is only accessible from the parent state. Not accessible from the child components that are building that parent state.

Thanks. Sorry if I am missing something.

@elboman
Copy link
Member

elboman commented Jul 17, 2017

Well, I guess the two main options here are:

  1. Using the UISref component (available only if the transition must occur when the user clicks something):
render () {
  return (
    <UISref to="mystate">
      <a>My state</a>
    </UISref>
  )
}
  1. Simply "pass down" the function, or even better, call it from the parent:
navigateToMyState () => {
  const {stateService} = this.props.transition.router;
  stateService.go('mystate');
}

render () {
  return (
    <Child onNavigate={this.navigateToMyState} />
  )
}

This way Child doesn't know about the router or how to navigate, it just needs to have a onNavigate prop which should be called when necessary. It's the (routed) Parent that takes care of navigating using the injected transition. This way you are separating concerns between the routed component and the "dumb" child components.

@roger-king
Copy link
Author

Gotcha, I passed down the function to the child and when try using the stateService.go

I receive this error:

Transition Rejection($id: 0 type: 6, message: The transition errored, detail: SecurityError: Failed to execute 'pushState' on 'History': A history state object with URL 'http://dashboard/' cannot be created in a document with origin 'http://localhost:8000' and URL 'http://localhost:8000/'.)`

stateService.ts:527 Error: Failed to execute 'pushState' on 'History': A history state object with URL 'http://dashboard/' cannot be created in a document with origin 'http://localhost:8000' and URL 'http://localhost:8000/'.

The code will route to the state but the url doesn't change to the states url.

@roger-king
Copy link
Author

Resolved the issue by adding the plugin: hashLocationPlugin

@elboman
Copy link
Member

elboman commented Jul 19, 2017

Wait, you weren't using a location plugin or did you simply change it from pushStateLocationPlugin? Because it should work with every location plugin.

Can you please show me your state declaration code? Because it looks like there's something off with the url there as it tries to completely replace the url from localhost:8000 to dashboard and the browser prevents it since the origin domain is different.

I guess you meant it to change to localhost:8000/dashboard when navigating to that state.

@roger-king
Copy link
Author

roger-king commented Jul 19, 2017

This is my state declaration:

export const DashboardState: ReactStateDeclaration = {
    name: 'dashboard',
    url: '/dashboard',
    component: Dashboard,
    data: {
        authenticate: true
    }
};

Here is my router config:

export const states = [Signup, Login, Dashboard];

export const plugins = [
servicesPlugin,
  hashLocationPlugin
];

export const config = (router: UIRouterReact) => {
  // Hook for if route is not registered.
  router.urlRouter.otherwise({ state: 'login' });

  router.transitionService.onBefore(
    {
      to: (state) => state.data && state.data.authenticate
    },
    (transition) => {
      let user = new UserService();
      let $state = transition.router.stateService;
      if (!user.isAuthenticated()) {
        return $state.target('login', undefined, { location: false });
      }
    },
    { priority: 10 });

  trace.enable(1);
};

Here is how I am initializing the UIRouter. ()

            <UIRouter plugins={plugins} states={states} config={config}>
                <div className="app-container">
                    <UIView />
                </div>
            </UIRouter>

Here is the ReactDOM render...

ReactDOM.render(
    <Provider {...stores}>
        <App />
    </Provider>,
    document.getElementById('root')
);

@elboman
Copy link
Member

elboman commented Aug 6, 2017

Still not sure, but I can see you are adding the servicesPlugin to the router while initialising it via the component and you shouldn't. The servicesPlugin is applied by default by the <UIRouter> component, and it's needed only if you want to bootstrap the router manually.

You haven't said if the fix by adding the hashStatePlugin was from not having a location plugin at all or by switching from the pushStatePlugin. Do you get the same error if you use pushStatePlugin instead?

@eddiemonge
Copy link
Member

As this issue is a bit old, it is being closed. If you feel like the problem reported is still valid, please add a comment saying it is still affecting you. We will reevaluate it and if it is valid we will reopen it.

Thank you for supporting and contributing to the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants