Is there some how to navigate to a page and pass parameters without use the address bar in Blazor?

Viewed 417

This is present in many modern SPA libraries/frameworks...

I will supply an example using React (But it could be Angular or Vue), you can do something like...

this.props.router.push({
  pathname: '/login-successfully',
  state: {
    userId: 'john',
    name: 'John Doe
  }
})

and then on the initialization of the "other-page" you will have:

const {state} = useLocation();
const { userId, name } = state; 

and you can render things like

<p>Welcome Back, {name}!</p>

Such feature is very useful in many scenarios, but by reading the documentation of routing in Blazor at https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-5.0 I cannot find anything. The NavigationManager just have those parameters:

public void NavigateTo (string uri, bool forceLoad = false);

Is there some equivalent approach that I can use ? I know a workaround by creating a singleton class, store the data over there and display on the login-successfully page, but I really hope to find something better as solution.

1 Answers

Okay, my first answer got me a thumbs down, as apparently the decades-old standard of passing data in the URL was "rubbish" (actual quote) so let me explain what I actually do in this kind of case. I'm not actually a big fan of passing data in a query string either, especially since in Blazor you rarely need to.

I wasn't joking when I said that I wouldn't navigate among pages that share a large amount of data. I consider each page a separate site, with its own loading and saving of information to the database. Unless I'm passing something very simple, like an ID in the URL, I would use components to switch sub-functions.

(Not tested code, but you can get the idea)

Main page: main.razor

@if (IsDoingSomethingWithData)
{
     <MyDoingSomethingWithDataComponent ID=variable_ID Name=variable_Name State=variableState />
}
else
{
     <input @bind=variable_state /><br />
     <input @bind=variable_ID /><br />
     <input @bind=variable_name /><br />
     <button @onclick="ToggleDoingSomething">Next</button>
}

@code {
     string variable_state;
     string variable_ID;
     string variable_name;
     bool IsDoingSomethingWithData;
     void ToggleDoingSomething(){
          IsDoingSomethingWithData = !IsDoingSomethingWithData;
     }
}

Component: MyDoingSomethingWithDataComponent

(i.e. the stuff that you would have navigated to, but in Blazor don't need to)

<div>Hello, @variable_name</div>
<div>Your ID is: @variable_ID</div>
<div>I understand that you live in state: @variable_state</div>

@code{
[Parameter]
string ID;

[Parameter]
string Name;

[Parameter]
string State;
}

If you actually make a project and do this-- use named parameters to initialize a component-- you'll see that it never gets hit, and upon inspection of the page, none of the component has been rendered, UNTIL you set IsDoingSomethingWithData = true;

Magic!

Related