I'm using Blazor with .NET Core 3.0. I want to show a login in my menu, when the user isn't logged in yet. When he is logged in, then the login nav item should be hidden. How can I do this?
EDIT: I changed the OnInitializedAsync method by using async Task, but this is not the problem. For the first load, it works correctly. But then i go to the login page, log me in and Navigate to the home page via NavigationManager, the menu will not be "refreshed". How can I solve this?
Following code is not working...
<div>
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
@if (!_isLoggedIn)
{
<li class="nav-item px-3">
<NavLink class="nav-link" href="login">
<span class="oi oi-person" aria-hidden="true"></span> <LocalizedString Key="NavMenuLogin" />
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="licenseedit">
<span class="oi oi-spreadsheet" aria-hidden="true"></span> <LocalizedString Key="NavMenuRegistration" />
</NavLink>
</li>
}
</ul>
</div>
@code{
private bool _isLoggedIn;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await TokenExistAsync();
}
private async Task TokenExistAsync()
{
var retVal = await Http.GetStringAsync("api/Login/ExistToken");
_isLoggedIn = retVal == "yes";
}
}
In the Pages/Shared directory open the NavMenu. razor file which is the file where the nav menu is defined. The following code is the code that renders the Fetch data menu item which is the section we want to hide if the user isn't logged in. To hide menu item we wrap the list item in the AuthorizeView component.
Access to browser navigation from Blazor is provided via the NavigationManager service. This can be injected into a Blazor component using @inject in a razor file, or the [Inject] attribute in a CS file. The NavigationManager service has two members that are of particular interest; NavigateTo and LocationChanged .
You can redirect to a page in Blazor using the Navigation Manager's NavigateTo method. In the following code snippet, it will redirect to the home page when this page gets loaded. Similarly, you can call NavigateTo() method from NavigationManager class anywhere to redirect to another page.
I changed my code above, but still not working
I think I understand what you want... The following is the code to achieve that, provided that I'm right... You want to refresh the content of the NavMenu component, which is embedded in the MainLayout component, from the login page, right?
You can use various methods to achieve this. The following solution is based on the App State Pattern.
First off, we have to create a service class that can be accessed from both, the NavMenu component and the Login component. Here's the class:
public class AppState
{
private bool _loggedIn;
public event Action OnChange;
public bool LoggedIn
{
get { return _loggedIn; }
set {
if (_loggedIn != value)
{
_loggedIn = value;
NotifyStateChanged();
}
}
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
This class defines an event delegate, named OnChange, which should encapsulate the method that will refresh the NavMenu. This delegate is invoked when the boolean property LoggedIn's value changes. The LoggedIn property's value may change in the Login page, when the user has been logged in, thus any subscriber to this delegate, in our case, the NavMenu, will be notified of this.
@inject AppState AppState
Note the above inject the AppState to the Login Page. Put it at the top of the page
AppState.LoggedIn = true;
that code should be place at the end of the log in procedure. This will initiate the triggering of the OnChange delegate.
@inject AppState AppState
@implements IDisposable
*
protected override void OnInitialized()
{
AppState.OnChange += StateHasChanged;
}
public void Dispose()
{
AppState.OnChange -= StateHasChanged;
}
Now, whenever you log in, the AppState service notifies the NavMenu component to re-render so that the login link is not visible (not rendered)
services.AddSingleton<AppState>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With