Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NavLink updating URL but does not reloading page in Blazor

I have a ProjectBase.razor page that is used to create, view & edit projects. The following routes all take you to this page:

/project/view/{projNum}
/project/create/
/project/edit/{projNum}

I also have a Navlink in my navigation menu that allows you to create a new project:

<NavLink class="nav-link" href="/Project/Create" Match="NavLinkMatch.All" >
    <span aria-hidden="true">New Project</span>
</NavLink>

If I click on that link while on the view/edit features of the same page, the URL changes to "/Project/Create," but the page itself doesn't refresh or reload. Is there a way to force this through the NavLink? Or do I need to add an OnClick function to do this?

like image 396
Katie P Avatar asked Jan 02 '20 18:01

Katie P


People also ask

How do I force a Blazor reload page?

A page is reloaded/refreshed automatically at a specified interval using “NavigationManager” in OnAfterRender() method. Here the NavigateTo(“url”, forceLoad: true) method, is used to force load the browser based on the URI.

How do I get the current URL in Blazor Webassembly?

Inject NavigationManager in razor. Use Uri from NavigationManager to get the current URL.

How do you Rerender a component in Blazor?

To force a component to rerender, use the “StateHasChanged” method in Blazor, to notify that the state has been changed and requires re-rendering.

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.


6 Answers

Create and use the OnParametersSetAsync task in your code block for the page. This event will fire when parameters change.

@code
protected override async Task OnParametersSetAsync()
{
// This event will fire when the parameters change
// Put your code here.  

}
like image 108
Rod Weir Avatar answered Oct 12 '22 17:10

Rod Weir


Yes, using something like Microsoft.AspNetCore.Components.NavigationManager and its NavigateTo function with forceLoad set to true will accomplish what you're looking for.

Of course yes, this will require you to set up an onclick function, but this is the way I ended up accomplishing something similar for a site-wide search page which never technically had its URL change outside of the query string search value I was passing it.

That being said, there may be a decent way of doing it with only NavLinks. I'll update my answer when I'm not on mobile.

like image 43
GrowingCode247 Avatar answered Oct 12 '22 18:10

GrowingCode247


I had same problem. Solution I have is...

Create new page

@page "/project/create/"
<ProjectBase></ProjectBase>

That's it! remove @page directive for(/project/create/) from ProjectBase page

Everything will work as expected... now do it for all pages you have.

like image 44
PhotoSonic Avatar answered Oct 12 '22 17:10

PhotoSonic


In my component I had already overridden OnInitializedAsync in order to make an API call to get my data.

My solution looks like this:

        protected override async Task OnInitializedAsync()
        {
           // Make your API call or whatever else you use to initialize your component here
        }

        protected override async Task OnParametersSetAsync()
        {
            await OnInitializedAsync();
        }
like image 30
Brendan Sluke Avatar answered Oct 12 '22 16:10

Brendan Sluke


In your case you have to make below changes as mention by Rod Weir, I am just extending the answer.

 /project/view/{projNum}
 /project/create/
 /project/edit/{projNum}

For above query parameter you have to define [Parameter] in your code.

[Parameter]
public string projNum {get;set;}

Then add method

protected override async Task OnParametersSetAsync()
{

  var projectDetail = await getProjectDetails(projNum); // ProgNum will change as it get changes in url, you don't have to do anything extra here.
}

Force page to reload will land you in some other problems, it will get the correct result but the page behavior will change. There are other components on the page like header/left Nav/ etc these will not changes if they are dynamic. It will force you to make changes and hanlde force reload in all the components. Also user experience is affected.

Hope this help.

like image 29
ZKS Avatar answered Oct 12 '22 18:10

ZKS


That is by design.The page itself doesn't refresh or reload because the <NavLink> does not send request to the server (F12 to check) and it redirect to the same page on the client, so nothing updates.

If you enter those URLs in the browser,they will send requests and then refresh page.

A workaround is that you could display different content based on the current route.

@page "/project/view/{projNum}"
@page "/project/create/"
@page "/project/edit/{projNum}"
@using Models
<h3>ProjectBase</h3>

@if (projNum == null)
{
<EditForm Model="@createModel" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputText id="name" @bind-Value="createModel.Name" />

    <button type="submit">Create</button>
</EditForm>
}
else
{


<EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputText id="name" @bind-Value="exampleModel.Name" />

    <button type="submit">Submit</button>
</EditForm>
}
@code {


    [Parameter]
    public string projNum { get; set; }

    private ExampleModel createModel = new ExampleModel();
    private ExampleModel exampleModel = new ExampleModel();

    protected override void OnInitialized()
    {
        exampleModel.Name = projNum;
    }



    private void HandleValidSubmit()
    {
        //your logic
        Console.WriteLine("OnValidSubmit");
    }
}
like image 44
Ryan Avatar answered Oct 12 '22 17:10

Ryan