TiGreX
TiGreX

Reputation: 1816

blazor not changing the page when clicking on a link

I am migrating my personal blog to Blazor, and I have a problem. I was developing the "next post" functionality and blazor (or the browser) is not redirecting the user when a link is clicked. the post are "the same page" under the next route @page "/post/{Url}

For example the user is in domain.com/post/foo and in that site there is a link to domain.com/post/bar. It is a simple link, like the next:

<a href="post/bar" title="@Post.Title">
    @Post.Title 
</a>

When the user clicks on the link the url for the browser changes, and the location of the page moves to the top, but the page content is not changing.

I noticed that this behaviour is happening when I click from a post page into another, but is not happening from the "index" of the site (/) or when I click the tags on the post, which links to domain.com/tags/{tag}.

one thing to notice is that if I select the url in the browser and click enter or refresh the page it actually goes to the page i clicked on, in this case domain.com/post/bar

My question is, is this actually expected behavior or is it a bug? if it is expected behaviour, is there any way of making the url to actually go to the clicked url and not stay in the same page.

I am using net5.0 if that matters.

Thanks.

Upvotes: 1

Views: 5576

Answers (3)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30001

Answer withdrawn as it breaks some component parameter recommendations by ASPNetCore Team - see https://github.com/dotnet/aspnetcore/issues/24599

Upvotes: 0

enet
enet

Reputation: 45586

when I click from a post page into another

post in domain.com/post/foo and domain.com/post/bar is definitely not a page but a literal path segment.

I've created a routable component named Foo:

Foo.razor

@page "/post/foo"

@code {
}

Foo is a routable component; that is, it is a page, and can be accessed by typing the url in the address bar of your browser, using an anchor element or the NavigationManager. You may embed it in a parent component as well.

post is, as I've said above, a literal path segment

But if you insist that post is actually a component page, then I guess it may look something like this:

Post.razor

@page "/post"
@page "/post/{Param}"
<a href="post/bar" title="Title">
Title 
</a>

<div>@Param</div>
@code {

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

Now, when you type in the address bar a url like this: https://localhost:<port-number>/post

You'll be navigated to the post routable component (page)

If you click on the anchor element, the url in the address bar will change to https://localhost:<port-number>/post/bar

bar is not a component; it is a parameter. The address bar changes, but you seem to be in the same post component, the data or content, however, do changes...

Note that when you click on the anchor element, you are being navigated to a new Url ("post/bar"), but rendering engine does not create a new instance of the Post component in order to render the page, but instead it treats it as the same page with changed parameters. Thus it looks like no navigation has taken place, and nothing has changed, except the url in the address bar. I'm not claiming that your issue is the same, but it may stem from similar code usage. Note that since Blazor does not create a new component instance, but uses the existing one, the OnInitialized(Async) pairs can only run once... So you'll have to use the SetParametersAsync method (" on initializedAsync is getting the "nextPost" information from the backend, but its just a plain http cal")

All the above was intended to ask you to do the simplest thing and provide the route templates........

Is bar a component? Is foo a component?

Upvotes: 0

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30001

As an add on to @enet's answer, you're probably fetching the post referenced by the Url property in OnInitialized/OnInitializedAsync. See the last long paragraph in @enet's answer.

One way to address this is:

  • place the code to load data in a separate method say LoadDataAsync
  • in SetParameters/SetParametersAsync detect if the data reference - in your case Url - has changed in , and if so call LoadDataAsync.

The key here is understand component lifecycle and getting the code in the right place.

Put breakpoints in on OnInitialized and SetParameters and watch when they get hit when you load and do navigation.

Upvotes: 1

Related Questions