Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change visibility of nav item in blazor menu

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";
    }

}
like image 727
everydayXpert Avatar asked Jan 07 '20 13:01

everydayXpert


People also ask

How do you hide NavMenu in Blazor?

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.

How do you use the Blazor NavigationManager?

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 .

How do I navigate to another page in Blazor?

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.


1 Answers

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.

Login Page

  • @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.

NavMenu component

  • @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)

Startup class

services.AddSingleton<AppState>();
like image 146
enet Avatar answered Oct 26 '22 13:10

enet