How to refresh the child razor component on the bases of provided text box which is resided in parent razor component (by using a razor class library)?

mehmood tekfirst 771 Reputation points
2022-06-02T13:49:29.027+00:00

Hi,

I need to refresh the child razor component on the bases of provided text box which is resided in parent razor component (by using a razor class library)

What I want that ASAP user type 5th character or more in the textbox , a call should go the server and bring the result set and on the bases of retrieved result set,

child component should be refreshed but with best practice.

_Imports.razor under RCL Project is as follows:

 @using System.Net.Http  
  @using Microsoft.AspNetCore.Authorization  
  @using Microsoft.AspNetCore.Components.Authorization  
  @using Microsoft.AspNetCore.Components.Forms  
  @using Microsoft.AspNetCore.Components.Routing  
  @using Microsoft.AspNetCore.Components.Web  
  @using Microsoft.JSInterop   
  @using System.IO  
  @using CarRentalWidget.Models.DBEntities.Franchises
  @using CarRentalWidget.Models.ViewModels.GooogleGeoCodes
  @using CarRentalWidget.RCL.CarWidgetUI.Pages

AutoCompleteLocationsComponent.razor is as follows:

@using System.Net.Http
 @using System.Net.Http.Json
 @using System.Threading.Tasks
 @inject HttpClient Http
 @namespace CarRentalWidget.RCL.CarWidgetUI.Pages
 <div>
                 <input
                     type="text"
                     id="TxtBxPickUpLoc"
                     class="postcode tf-form-control"
                     placeholder="Please Enter Postcode or Town"                                      
                    value="@inputValue"
                     @oninput="OnInputValueChanged"   
                     autoComplete="off"
                 />
                             @if(!string.IsNullOrWhiteSpace(inputValue))
                             {
                                 <a className="location" href="#" id="branch-selector" onClick={onClearLocations}></a>
                             }
                             else if (string.IsNullOrWhiteSpace(inputValue))
                             {
                                 <a className="location empty" href="#" id="branch-selector" onClick={onClearLocations}></a>
                             }

         </div>
       @if (!string.IsNullOrWhiteSpace(inputValue))
{
    <div class="sautocomplete-content-container tk-search-drop-wrapper ac-drop-active">
        <div class="sautocomplete-content tk-search-drop">
            <div class="branch-info">                          
                <ul id="LocationSuggestions" class="suggestions">
                    @if (locationData != null && locationData.Count() > 0)
                    {
                        <LocationsList @key="locationData" Data="@locationData"/>
                    }                
                </ul>                              
            </div>
        </div>
    </div>
}



    @code {
        private string inputValue = "";
    //private string className = "";
    //private int activeSuggestionIndex;
    //private int index = 0;  
    private FranchiseWebInquiry[]? locationData;
    private bool getError;
    private bool shouldRender;

    protected override bool ShouldRender() => shouldRender;
    private GoogleGeocode? currentMapItems;  

         private async Task<GoogleGeocode?> loadGoogleGeoCodeData(string postCodeOrTown)
         {
             currentMapItems = await Http.GetFromJsonAsync<GoogleGeocode?>
             ("https://maps.googleapis.com/maps/api/geocode/json?types=geocode&language=en&key=mykey&address=" + postCodeOrTown);
             return currentMapItems;
         }

         private async Task getLocationsApi(string postCodeOrTown)
         {
             await loadGoogleGeoCodeData(postCodeOrTown);
             Result? serviceResult = currentMapItems!.Results!.FirstOrDefault();
             Location? locDetail = serviceResult != null && serviceResult.Geometry != null ? serviceResult.Geometry.Location:null;
             double providedLattitude = locDetail != null ? locDetail.Lat : 0;
             double providedLongitude = locDetail != null ? locDetail.Lng : 0;
             locationData = await Http.GetFromJsonAsync<FranchiseWebInquiry[]?>
             ("https://localhost:7177/api/CarRental/allfranchises/?postCodeOrAddress=" + postCodeOrTown + "&lattitude=" + providedLattitude + "&longitude=" + providedLongitude);             
         }

 public EventCallback<string> InputValueChanged { get; set; }   

 private async Task OnInputValueChanged(ChangeEventArgs e)
    {
        inputValue = e.Value!.ToString()!;   

            if (inputValue!.Length >= 5)
            {
                await getLocationsApi(inputValue);
                 RefreshComponent();
            }        

        await InputValueChanged.InvokeAsync(inputValue);
    }
         private async void DoChangeLocation(ChangeEventArgs e)
         {
             inputValue = e.Value!.ToString();
             if (inputValue!.Length >= 5)
             {
                await getLocationsApi(inputValue);         
             }
             Console.WriteLine("It is definitely: " + inputValue);
         }    

     private void RefreshComponent()
    {
        StateHasChanged();
    }
}

and Index.cshtml is as follows:

 @page "/car-index"
 @model CarRentalWidget.RCL.CarWidgetUI.Pages.IndexPageModel

 <!DOCTYPE html>

 <html>
 <head>
     <meta name="viewport" content="width=device-width" />
     <title>Car Rental Widget</title>
 </head>
 <body>
     <div class="widget-wrapper">
             <div class="main-heading">
                 <h1>               
                     Test 1
                 </h1>                 
             </div>
             <div class="widget-slider">
                 <div class="row step-row">
                     <div class="col-12">
                         <div class="pickup-location tf-search-group">
                             <div class="label-location tf-search-label">pick up location</div>
                             <div id="PickUpLocationControlId" class="input-group-location tf-search-field">                                                                               
                                 <div class="card">   
                                 @(await Html.RenderComponentAsync<CarRentalWidget.RCL.CarWidgetUI.Pages.AutoCompleteLocationsComponent>
                                     (RenderMode.ServerPrerendered/*,new {  Data="I came from Index",style= "badge-danger" }*/))  
                                  </div>                               
                             </div>                                                        
                         </div>
                     </div>                  
                 </div>
             </div>
     </div>
 </body>
 </html>

LocationList.razor is as follow:

@namespace CarRentalWidget.RCL.CarWidgetUI.Pages

@if (Data != null && Data.Count() > 0)
                {
                    @foreach (FranchiseWebInquiry suggestion in Data!)
                    {
                        // Flag the active suggestion with a class
                        if (index == activeSuggestionIndex)
                        {
                            className = "suggestion-active";
                        }
                        <li class="@className" key="@index + @suggestion.FranchiseName" onClick="onClick(suggestion)">
                            <a pickupid="@suggestion.PickupId + @suggestion.FranchisesId"  franchisesid="@suggestion.FranchisesId" subofficeid="@suggestion.SubOfficeId" href="#">
                                <span class="locName">@suggestion.FranchiseName</span>
                                <span class="locDetails">@getAddress(suggestion)                                            
                                </span>
                            </a>
                        </li>
                        ++index;
                    }
                }

@code {
        private bool shouldRender;
         [Parameter]  
         public FranchiseWebInquiry[]? Data { get; set; } = null;         
         private string className = "";
         private int activeSuggestionIndex = 0;
         private int index = 0; 
        // public FranchiseWebInquiry[]? PrevousData { get; set; } = null;  
        // protected override void OnParametersSet()
        //{
        //    shouldRender = Data != PrevousData;
        //    PrevousData = Data;
        //}

        //protected override bool ShouldRender() => shouldRender;

         private string getAddress(FranchiseWebInquiry suggestion)
         {
            //debugger;
           string localAddress = "";
           if(suggestion != null){
              if(!string.IsNullOrWhiteSpace(suggestion.Address1)){
                    localAddress =  suggestion.Address1 + " , ";
               }                  
               if(!string.IsNullOrWhiteSpace(suggestion.Address2)){
                    localAddress += suggestion.Address2 + " , ";
               }
               if(!string.IsNullOrWhiteSpace(suggestion.Address3)){
                    localAddress += suggestion.Address3 + " , ";
               } 
               if(!string.IsNullOrWhiteSpace(suggestion.Town)){
                    localAddress += suggestion.Town + "- " + (!string.IsNullOrWhiteSpace(suggestion.PostCode) ? "(" + suggestion.PostCode + "), ":"");
               }
               if(!string.IsNullOrWhiteSpace(suggestion.PrimaryContact))
               {
                    localAddress += suggestion.PrimaryContact;
               }           
            }
             return localAddress;  
        }
}
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,189 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,016 Reputation points Microsoft Vendor
    2022-06-03T07:35:36.613+00:00

    Hi @mehmood tekfirst ,

    <LocationsList [@](/users/na/?userId=a549174b-f4bc-4c2e-8aa7-47b918f260d4)="locationData" Data="@locationData"/>    
    

    From your code, it seems that you want to transfer data from parent component to the child component. If that is the case, you could use the Component parameters and the @bind-{PROPERTY} syntax.

    For example:

    208155-image.png

    and

    208077-image.png

    More detail information, see Binding with component parameters.

    Update:

    Here is another method to transfer data from parent to child component:

    Pages/ParameterParent.razor:

    208107-image.png

    Pages/ParameterParent.razor:

    208070-image.png

    Refer this article: Component parameters


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. mehmood tekfirst 771 Reputation points
    2022-06-03T07:44:29.163+00:00

    Thank you ZhiLv-MSFT.

    ZhiLv, Can we render razor component in browser rather than on server mode ?