C# random behaviour in a CRUD edit page.

sblb 1,166 Reputation points
2022-10-14T14:09:47.947+00:00

Hi,
My application has a strange behaviour for a function I put with the help of @AgaveJoe . Definition link to generate a variable ECO [WebApiSqlite][1]

Normally the ECO variable is generated when I validate the checkboxValue1 and then I validate the Edit page.

Now the ECO variable is generated without validating the checkboxValue1 variable. The variable ECO is generated when I validate the Edit page without the checkboxValue1 variable being validated.

Edit.razor

<FormEdit ButtonText="Update" dev="dev"  
  OnValidSubmit="@EditDeveloper" />  
@code {  

    [Parameter] public int developerId { get; set; }  
    Developer dev = new Developer();   

    protected async override Task OnParametersSetAsync()  
    {  
        dev = await http.GetFromJsonAsync<Developer>($"api/developer/{developerId}");  

    }  

    async Task EditDeveloper()  
    {  
       await http.PutAsJsonAsync("api/developer", dev);        
       await http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
       await js.InvokeVoidAsync("alert", $"Updated Successfully!");  
       uriHelper.NavigateTo("developer");          
    }          

}  

as you can see on picture below ECOSelected is false.
![250593-image.png][3]

the uriHelper.NavigateTo("developer");

The fetchData .razor is active to update and fetch the data and ECOSelected become true.
250518-image.png

How to avoid what the variable ECOSelected stay false when checkboxValue is false? and
when if checkboxValue1 = true then ECOSelected = true?

ECOSelected ECO variable is defined in model class

public bool ECOSelected { get; set; }  
        [NotMapped]  
        public string ECO   
        {  
            get  
            {  
                if (ECOSelected)  
                {  
                    return $"{ECOCount.ToString().PadLeft(3, '0')}/{ECOYear}";  
                }  

                return string.Empty;  
            }  
            set { }  
        }  

The controller

  [HttpGet("SelectEcoById/{id}")]  
         public async Task<ActionResult<Developer>> SelectEcoById(int id)  
        {  
            var developer = await _context.Developers.FindAsync(id);  
            if (developer == null)  
            {  
                return NotFound();  
            }  
            if (!developer.ECOSelected)  
            {  
               var values = await GenerateEcoByIdAsync(id);  

                    developer.ECOYear = values.Year;  
                    developer.ECOCount = values.Count;  
                    developer.ECOSelected = true;  


                await _context.SaveChangesAsync();  
            }  

            return developer;  
        }  

[1]: https://github.com/mjgebhard/WebApiSqlite+ [3]: /api/attachments/250593-image.png?platform=QnA

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,390 questions
0 comments No comments
{count} votes

11 answers

Sort by: Most helpful
  1. sblb 1,166 Reputation points
    2022-10-16T14:01:51.247+00:00

    In Edit.razor I added one condition

    if(dev.ECOSelected == true)  
    {  
     await http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
    }  
    

    And I added in FormEdit.Razor the condition

    <input @bind-Value=@checkBox1Value type="checkbox"  />   
    @if(checkBox1Value == true){dev.ECOSelected = true;}  
    

    I've put a breakpoint here await http.GetAsync($"api/developer/SelectEcoById/{developerId}"); and the controller it didn't call.

    Have you an idea?

    0 comments No comments

  2. sblb 1,166 Reputation points
    2022-10-16T14:25:50.007+00:00

    I solved part of the problem because now as the ECOSelected is always true the ECO variable is incremented at each setting of the Edit page.

    Have you an idea how I can to do it?

    0 comments No comments

  3. sblb 1,166 Reputation points
    2022-10-16T16:24:49.293+00:00

    It's here that I've to change but I don't how I can do it?

    async Task EditDeveloper()  
        {  
            await http.PutAsJsonAsync("api/developer", dev);  
        //  if (dev.ECOSelected==true)  
          //{  
            await http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
        //  }          
           await js.InvokeVoidAsync("alert", $"Updated Successfully!");  
           uriHelper.NavigateTo("developer");          
        }  
    

    This means the condition on ECOSelected it's always true. How I can call the Controller SelecEcoById only when the checkbox is true?

    Thanks in advance to your help!!


  4. sblb 1,166 Reputation points
    2022-10-17T10:12:07.543+00:00

    Hi, thanks to your reply.

    In my application I have two files : Edit.razor and FormEdit.razor.

    Edit.razor :

    <FormEdit ButtonText="Update" dev="dev"  
       OnValidSubmit="@EditDeveloper" />  
     @code {  
          
         [Parameter] public int developerId { get; set; }  
         Developer dev = new Developer();   
          
         protected async override Task OnParametersSetAsync()  
         {  
             dev = await http.GetFromJsonAsync<Developer>($"api/developer/{developerId}");  
          
         }  
          
         async Task EditDeveloper()  
         {  
            await http.PutAsJsonAsync("api/developer", dev);        
          //  await http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
            await js.InvokeVoidAsync("alert", $"Updated Successfully!");  
            uriHelper.NavigateTo("developer");          
         }          
          
     }  
    

    If I don't want to call the api when I update edit page I must not put here await http.GetAsync($"api/developer/SelectEcoById/{developerId}");

    FormEdit.razor

    <EditForm Model="@dev" OnValidSubmit="@OnValidSubmit">  
        <DataAnnotationsValidator />  
      
    <InputCheckbox @bind-Value="dev.ECOSelected" />     
      
    @code{  
      
       [Parameter] public Developer dev { get; set; }  
        [Parameter] public EventCallback OnValidSubmit { get; set; }  
        [Parameter] public int developerId { get; set; }  
      
          
     private async void HandleValidation()  
        {  
          //  Logger.LogInformation("HandleValidSubmit called");  
            var checkboxvalue = dev.ECOSelected;  
      
             
          await  http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
      
        }  
    }  
    

    So, I've to call the api method in FormEdit but I don't know how I can do it?

    try to use the InputCheckbox component and bind the value using dev.

    So, I don't know how I can bind the value from InputCheckbox and dev

    0 comments No comments

  5. sblb 1,166 Reputation points
    2022-10-17T15:41:43.263+00:00

    To bind the value from InputCheckbox and dev

    <InputCheckbox @bind-Value="dev.ECOSelected" />  
    

    Finally I've to call the api in Edit.razor as below :

     async Task EditDeveloper()  
        {  
            await http.PutAsJsonAsync("api/developer", dev);  
            Console.WriteLine($"Checkbox changed {dev.ECOSelected}");  
      
           await http.GetAsync($"api/developer/SelectEcoById/{developerId}");   
         
           await js.InvokeVoidAsync("alert", $"Updated Successfully!");  
           uriHelper.NavigateTo("developer");          
        }      
    

    With this configuration I call the api

       [HttpGet("SelectEcoById/{id}")]  
             public async Task<ActionResult<Developer>> SelectEcoById(int id)  
            {  
                var developer = await _context.Developers.FindAsync(id);  
                if (developer == null)  
                {  
                    return NotFound();  
                }  
                 
                if (developer.ECOSelected)  
                {  
                   var values = await GenerateEcoByIdAsync(id);  
                      
                        developer.ECOYear = values.Year;  
                        developer.ECOCount = values.Count;  
                        developer.ECOSelected = true;                    
      
                    await _context.SaveChangesAsync();  
                }  
      
                return developer;  
            }  
    

    When I edit the page for the first time I can validated the InputCheckbox. The api is called and the value is rendered;

    So Right now, if I edit a second time dev.ECOSelected is always true this means the number is a second time incremented. How I can stop the incrementation after the first edition?

    I have been around the issue for some time and it still doesn't work!