In a Maui Xaml app, i have a page and its viewmodel with an ObservableCollection
of items that i want to retrieve with an api call.
I want to have the api call in another service where all those same api calls are placed.
I'm using Maui CommunityToolkit mvvm etc by the way, so the InitializeCommand
is binded to the UI with the eventToCommmandBehaviour OnAppearing
.
What I want to archieve is that items get added while they arrives and not in a block like normally reading the response and materializing the items in an array.
In the view model I have:
private async Task InitializeCommand()
{
items.Clear();
var result = await _apiService.GetItemsAsync();
await foreach(var item in result)
{
items.Add(item);
}
}
The apiService method does this:
public async Task<IAsyncEnumerable<Item>> GetItemsAsync()
{
using var client = httpClientFactory.CreateClient();
using var response = await client
.GetAsync("myUrl", HttpCompletionOption.ResponseHeadersRead)
using var stream = await response.Content.ReadAsStreamAsync();
return JsonSerializer.DeserializeAsyncEnumerable<Item>(stream);
}
Now there is a problem in this method, with the using
keyword. First of all i'm not sure if I need to specify it 3 times, for the client
, the response
and the stream
.
But this aside, by disposing the response
as soon as it goes out of scope, you get an exception when consuming it in the InitializeCommand
method!
I'm not sure how to dispose of all of this request in the proper manner, without doing it on the caller side.
Also does calling await.Response.Content.ReadAsStreamAsync();
wait for all the stream to be read before continuing? I don't want that, i want the deserialization to the IAsyncEnumerable
to start as soon the headers are read.
Should i return the stream and deserialize it in the calling method and then dispose of it?