dsuryd / dotNetify

Simple, lightweight, yet powerful way to build real-time web apps.
https://dotnetify.net
Other
1.17k stars 164 forks source link

Redirect not available #201

Closed epsmae closed 5 years ago

epsmae commented 5 years ago

I use an AppLayout view which consists of the Header Sidebar and the content. All my routes (eg settings and about) are declared in the AppLayoutViewModel.

I am trying to change the page from the settings page to the about view. As mentioned in the documentation https://dotnetify.net/core/api/routing I should use redirect for this. However on the router I do not have a redirect.

Am I missing something?

import React from 'react'
import dotnetify, { dotnetifyVM } from "dotnetify";
import auth from "../auth";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import ThemeDefault from "../styles/theme-default";
import Paper from "material-ui/Paper";
import RaisedButton from 'material-ui/RaisedButton';

interface IProps { }

interface IState { }

class SettingsView extends React.Component<IProps, IState> {
    vm: dotnetifyVM;
    dispatch: (state: any) => any;

    constructor(props) {
        super(props);
        this.vm = dotnetify.react.connect("SettingsViewModel",
            this,
            {
                exceptionHandler: ex => {
                    alert(ex.message);
                    auth.signOut();
                }
            });

        this.state = { } as IState;
    }

    componentWillUnmount() {
        this.vm.$destroy();
    }

    render() {
        const styles = {
            paper: {
                padding: 20,
                margin: 20,
                overflow: "auto"
            }
        };

        return (
            <MuiThemeProvider muiTheme={ThemeDefault}>
                <div>
                    <Paper style={styles.paper}>
                        <RaisedButton
                            label="About"
                            primary={true}
                            // redirect not available on router
                            onClick={() => dotnetify.react.router.redirect('/AboutView')}/>
                    </Paper>
                </div>
            </ MuiThemeProvider>
        );
    }
}

export default SettingsView
dsuryd commented 5 years ago

Redirect is a server-side API:

public class SettingsViewModel : BaseVM, IRoutable
{
    public Route AboutView => this.Redirect("about");
   ...
}

Client-side:

   onclick={() => this.vm.$routeTo(this.state.AboutView)}
epsmae commented 5 years ago

Hi @dsuryd thanks for pointing me in the correct direction. However I am still unable to get it working.

Redirect has two parameters I tried a few different combinations like: this.Redirect("./", "AboutView"); But i always get this error: TypeError: Cannot read property 'Templates' of null at dotnetifyReactVMRouter.route

I register the Routes in the ApplayoutViewModel like:

this.RegisterRoutes("/", new List<RouteTemplate>
            {
                ...
                new RouteTemplate(nameof(Route.AboutView)),
                new RouteTemplate(nameof(Route.SettingsView)),
            });

The urls look like this:

http://localhost:54010/SettingsView
http://localhost:54010/AboutView
dsuryd commented 5 years ago

Try initialize the RoutingState: public RoutingState RoutingState { get; set; } = new RoutingState(); and the redirect param ("/", "AboutView").

epsmae commented 5 years ago

@dsuryd with ("/", "AboutView") and RoutingState initialized I don't get any log output but the page gets changed neither =(

dsuryd commented 5 years ago

Turn on client debugging (dotnetify.debug = true); there will be log outputs as it tries to resolve the route.

Also, you can reference dotnetify react template for redirect example. The dashboard activities card has redirect link to the form page.

epsmae commented 5 years ago

I enabled debug in the constructor of the SettingsView

constructor(props) {
        super(props);   
        (dotnetify as any).debug = true;
        this.vm = dotnetify.react.connect("SettingsViewModel"...

There is no additional log visible when I click for route to just nothing happens!

I checked out the redirect of the form page and the only difference I saw was the register routes. If I also set the path I am able to get it to work. new RouteTemplate(nameof(Route.AboutView)) { UrlPattern = $"{nameof(Route.AboutView)}(/:id)" }, Route route = this.Redirect("AboutView", "1");

However like this a have an id in the url.

dsuryd commented 5 years ago

I think I found the problem. Given your setup, the redirect logic erroneously produces a path with two leading slashes. I have a workaround hack until a proper fix is released. Add the below code after the connect call:

const base = this.vm.$route;
this.vm.$route = route => base(route).replace(/^\/\//, '/');