-1

I'm trying to understand why the OnNext event doesn't work the way I want to make it works, and if there is a way to make it works.

By doing this, the subscription in the MainPage class never received the OnNext event. Certainly, if I write the subject in the InfoStorageService class, it works, but I would like to keep the subject in a separate class so that all other classes, that I can have, can use it and the MainPage class receives the data.

There are the code:

RxNetHandler Class to handle the subject

public class RxNetHandler
{
    public readonly ReplaySubject<List<InfoDto>> InfoSubject = new(1);

}

InfoStorageService Class To get data from external server

public class InfoStorageService
{
    private readonly RxNetHandler _rxNetHandler = new();

    private HttpClient _httpClient;
    private List<InfoDto> _infos = new();


    public InfoStorageService()
    {
        InitHttps();
    }


    public async Task GetInfosDetails()
    {
        var response = await _httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts?userId=1");
        var content = response.Content;

        if (response.IsSuccessStatusCode)
        {
            var jsonResponse = await content.ReadAsStringAsync();
            _infos = JsonConvert.DeserializeObject<List<InfoDto>>(jsonResponse);
        }
        else
        {
            throw new Exception(((int)response.StatusCode).ToString() + " - " + response.ReasonPhrase);
        }

        _rxNetHandler.InfoSubject.OnNext(_infos);
    }
 }

MainPage Class

public partial class MainPage : ContentPage
{
    private readonly RxNetHandler _rxNetHandler = new();
    private readonly InfoStorageService _infoStorage = new();
    private List<InfoDto> _infos = new();

    private IDisposable _disposed;

    public MainPage()
    {
        InitializeComponent();
        InitData();
    }

    // Methode that is triggered when the page appearing
    protected override void OnAppearing()
    {
        _disposed = _rxNetHandler.InfoSubject.Subscribe(
            infos =>
            {
                _infos = infos;
            },
            () =>
            {
                Console.WriteLine("[ completed ]");
            }
        );

    }

    // Methode to get data from the external server
    private async void InitData()
    {
        await _infoStorage.GetInfosDetails();
        InfoListView.ItemSelected += InfoListOnItemSelected;
    }

}

Thank you for your help

Julian
  • 5,290
  • 1
  • 17
  • 40
JBD
  • 568
  • 8
  • 25
  • Did you check what is called first ? You basically should subscribe before `GetInfosDetails` – Selvin May 02 '23 at 12:49
  • also `async void` ... without `await` ... smells baddly – Selvin May 02 '23 at 12:53
  • @Selvin I tried as you said to Subscribe before GetInfoDetails and it doesn't work – JBD May 02 '23 at 13:05
  • Do some debbuging ... You will not catch exception without await ... https://dotnetfiddle.net/pp1qCI – Selvin May 02 '23 at 13:09
  • @Selvin In your code there is no Rx.Net code. So I do not understand. :) – JBD May 02 '23 at 13:32
  • 1
    also ... you are using different instances of `ReplaySubject` ... but again ... you may end with `throw new Exception(...)` (so `OnNext` will never called) and you will never know about this exception – Selvin May 02 '23 at 13:35
  • @Selvin Yes, I saw, and the problem comes from this. You're right. But with my low knowledge of programming, I don't know what can I do. – JBD May 02 '23 at 13:37
  • @Selvin Well the solution was to make the class RxNetHandler ``static``. – JBD May 08 '23 at 13:23

1 Answers1

0

The solution was to make the class RxNetHandler static:

public static class RxNetHandler
{
    public static readonly ReplaySubject<List<InfoDto>> InfoSubject = new(1);

}
JBD
  • 568
  • 8
  • 25