1

I have a very basic component that fetches students lists and displays them, as you can see below:

@if(result == null) {
  <p> No students found </p>
}else{
  @foreach (var person in result){
    <b> @person.name </b>
  }
}


@code {
  [Parameter] public string Token { get; set; } 
  [Parameter] public string StudentsUrl { get; set; } 
  StudentsModel result;     

  protected override async Task OnInitializedAsync()
  {
    using (HttpClient client = new HttpClient())
    {
      client.DefaultRequestHeaders.Accept.Add(
        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")
      );

      client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
          System.Text.ASCIIEncoding.ASCII.GetBytes(
            string.Format("{0}:{1}", "", Token)
          )
        )
      );

      HttpResponseMessage response = client.GetAsync(StudentsUrl).Result;
      response.EnsureSuccessStatusCode();
      string responseData = await response.Content.ReadAsStringAsync(); 
      result = JsonConvert.DeserializeObject<StudentsModel>(responseData);
    }
  }
}

The component does it job well, but I need to use the data shown below in another component. The other component has a dropdown (<select> </select> tags) and inside these tags I want to display users list (i.e. @person.name)

So, my question is how do I avoid fetching the same API twice in two different components and simple use the data that is generated in this class, so I can use it in another component.

elektra
  • 55
  • 2
  • 19
  • 3
    Use a service to retrieve and store the data. Inject the service into both components or use a parent component that shares a Cascading context. – Brian Parker Aug 18 '22 at 12:43
  • Hi, thanks for the answer... is there a tutorial online on how to do this exactly? I am new to Blazor – elektra Aug 18 '22 at 12:54
  • 1
    Search dependency injection for Blazor or Cascading Values. I prefer injection however it is a little more complicated but not much its something you should become familiar with anyway. – Brian Parker Aug 18 '22 at 12:58
  • The solution is to get your data out of your UI and into a view service - See this question and answer - https://stackoverflow.com/questions/69558006/how-can-i-trigger-refresh-my-main-razor-page-from-all-of-its-sub-components-wit/69562295#69562295. There's also and article here - https://www.codeproject.com/Articles/5339316/Get-the-Data-out-of-Your-Blazor-UI – MrC aka Shaun Curtis Aug 18 '22 at 14:21
  • If the second component will be displayed inside first component, you can also use a parameter binding to pass the list in. – keithwill Aug 18 '22 at 14:27
  • @MrCakaShaunCurtis Thanks, but I thought in Blazor the UI and data were supposed to exist (or atleast it wasn't considered bad practice) - the model is not inside the component and I don't put services there ... so I don't know if there is a need to seprate the data and UI – elektra Aug 18 '22 at 14:30
  • @keithwill-the-upvoter No, the second component will not be displayed inside the first. The first just lists students in it's own page eg: page `/students` the second is another page `/manage-students` but they both need a logic to list students. I am trying not to repeat the code – elektra Aug 18 '22 at 14:32
  • You have just given an example of why do do need to separate your data from the UI. Code it as you wish, you did ask the question! I'll leave others to comment on good/bad practice. – MrC aka Shaun Curtis Aug 18 '22 at 14:42

1 Answers1

1

Expanding upon the comment of @Brian Parker

You can do it in different ways depends upon you,

  1. Dependency Injection.

First, Make a Model named Person.cs

public class Person
    {
        private List<string> name { get; set; } 
    }

Second, Then Goto Program.cs and register it as a service like this, builder.Services.AddScoped<Person>();

Third, Inject it into your Parent Component, @inject Person _person;

Last, Do a API call and save that data into this _person.

Then in your Other Component just inject this service again and it will give you that data since its registered as a scopped service.

Wajeeh Hasan
  • 175
  • 1
  • 8