C# random behaviour in a CRUD edit page.

sblb 1,231 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,583 questions
0 comments No comments
{count} votes

11 answers

Sort by: Most helpful
  1. sblb 1,231 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,231 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,231 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,231 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,231 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!


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.