Steven Deam
Steven Deam

Reputation: 577

Blazor NavigateTo reloading same page

I have maintenance task website that lists out the tasks for a machine. the MachineDetails page:

 @page "/MachineDetails/{MachineName}"
 @inherits MachineDetailsBase

 <h3>Machine Details for @Machine.MachineName</h3>
 <table class="table table-bordered table-striped table-hover">
    <thead>
        <tr>
            <th scope="col">Description</th>
            <th scope="col">Repeat<br />(Days)</th>
            <th scope="col">Exp Dur<br /> (Min)</th>
            <th scope="col">Next Due</th>
            <th scope="col">Owner</th>
            <th scope="col">Perform<br />Task</th>
        </tr>
    </thead>
    @foreach (var t in Machine.TasksForMachine)
    {
        <tr scope="row">
            <td>@t.TaskDescription</td>
            <td>@t.TaskRepeatDays</td>
            <td>@t.TaskMinutes</td>
            <td>@t.NextDue.Value.ToShortDateString()</td>
            <td>@t.TaskOwnerType</td>               
            <td style="text-align:center"><button class="btn btn-primary" @onclick="(() => ShowPerformTask(t.TaskId))"> <img src="/css/open-iconic/svg/check.svg" height="12" /></button></td>                
        </tr>
    }
</table>

The MachineDetailsBase is:

  public class MachineDetailsBase : ComponentBase
  {
    [Inject]
    public IMaintenancePMRepository repo { get; set; }
    [Inject]
    NavigationManager NavigationManager { get; set; }
    [Parameter]
    public string MachineName { get; set; }
    public MachineForTasks Machine {get;set;}        
    // other details

    protected override async Task OnInitializedAsync()
    {
        GetSelectedMachine(MachineName);
        EmployeeList = repo.GetEmployeeList().ToList();
        StatusLoookup = repo.GetStatusList().ToList();            
    }

    private void GetSelectedMachine(string inputName)
    {
        Machine= repo.GetAllEquipment().Where(m => m.EquipmentName == inputName).FirstOrDefault(); ;
    }

    public void ShowPerformTask(int  taskID)
    {
      NavigationManager.NavigateTo("/PerformTask/" + taskID.ToString());
    }

on the task page I perform the necessary work and then attempt to call the NavigationManager again to get back to the original page.

The relevant code on PerformTaskBase does the same basic thing code to get back:

razor page code:

        <div class="row">
            <div class="col-sm-4 ">
                <button class="btn btn-primary" @onclick="(() => ClosePerformTask(true))"> Save </button>
            </div>
            <div class="col-sm-4 ">
                <button class="btn btn-secondary" @onclick="(() => ClosePerformTask())"> Don't Save</button>
            </div>
        </div>

then the code behind:

  public void ClosePerformTask(bool SaveTask = false)
  {
     if (SaveTask)
        {                
            repo.PerformTask(TaskRecord);
            TaskToPerform.NextDue = DateTime.Today.AddDays(TaskToPerform.TaskRepeatDays.GetValueOrDefault());
            repo.UpdateTask(TaskToPerform);                
        }

        NavigationManager.NavigateTo("/MachineDetails/" + MachineID);
    }

the MachineDetails page loads for a split second, then the PerformTask page opens back up.

Putting breakpoints in the code behind of the MachineDetails page, I don't see anything other than the OnInitializedAsync() fire at all. How can I get the MachineDetails page to load and not return back to the PerformTask?

Upvotes: 0

Views: 2272

Answers (1)

enet
enet

Reputation: 45586

My answer is based on the supposition that this code is residing within a form element...

div class="row">
        <div class="col-sm-4 ">
            <button class="btn btn-primary" @onclick="(() => 
           ClosePerformTask(true))"> Save </button>
        </div>
        <div class="col-sm-4 ">
            <button class="btn btn-secondary" @onclick="(() => 
                        ClosePerformTask())"> Don't Save</button>
        </div>
    </div>

Am I right.

If yes, the explanation for this behavior is very simple: Using the input button without setting up the type attribute is equivalent to setting up the type attribute to submit. When you click on either buttons a traditional post back to the server takes place in addition to the navigation by the NavigationManager. But you do not post back in an SPA app. This means going out of the navigation space of your application... To remedy this, add the type attribute to both buttons with button value: <button type="button"> This won't allow the post back, and the Navigation will occur as expected.

Hope this helps...

Upvotes: 3

Related Questions