Signal R how properly take data from events?

Viewed 44

My problem is: I subscribed to events in signalR, but I don’t understand how to correctly take the data from this answer and put it in UI. The documentation shows the same method as in my code, but an empty list is returned to me in the user interface. In my case i get the data at the moment when the event comes, until i get the data from the event the list is empty and i thought to capture this data somehow, because i have to show it to the user. But the data from the event is not coming to my UI

But there is data in the console. Here they are - [{warpedBox: [604.3993, 290.7302, 1106.364, 290.7302, 1106.364, 530.2628, 604.3993, 530.2628], name: Cats, date: 2022-09-05T09:01:11.9003992+03:00, additionInfo: new animal detected, baseName: TestBase, imageGuid: 00000000-0000-0000-0000-000000000000}] . How to get data from an event?

Many thanks to Robert Sandberg

I made some changes and now my code is like that (also I added UI part, because I don't understand how to make it work)

My code is now:

typedef CallbackFunc = void Function(List<dynamic>? arguments);
 

   class Animals {
      Alarmplayer alarmplayer = Alarmplayer();
    
      Future<void> fetchAnimals(CallbackFunc arguments) async {
        final httpConnectionOptions = HttpConnectionOptions(
            accessTokenFactory: () => SharedPreferenceService().loginWithToken(),
            skipNegotiation: true,
            transport: HttpTransportType.WebSockets);
        final hubConnection = HubConnectionBuilder()
            .withUrl(
              'secure_link',
              options: httpConnectionOptions,
            )
            .build();
        await hubConnection.start();
        hubConnection.on('Animals', (arguments);
 alarmplayer.Alarm(url: 'assets/wanted.mp3', volume: 0.01);
          await Future.delayed(const Duration(seconds: 2))
              .then((value) => alarmplayer.StopAlarm());
        });
      }
     return agruments
    }

My UI-part:

  class _TestScreenState extends State<TestScreen> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: FutureBuilder<void>(
///can't understand how to pass here arguments
              future: fetchAnimals(),
              builder: (context, snapshot) {
                return ListView.builder(
                  itemCount: snapshot.data?.length ?? 0,
                  itemBuilder: (context, index) {
                    return Column(children: [
                      Text(snapshot.data?[index]['name']),
                    ]);
                  },
                );
              }),

I am sorry but I am really noob in that and can't understand how can I use it in the UI

1 Answers

If I understand you correctly, then you mean that you get an empty list where you do the print(detectedAnimals ); ? With this setup, your method will basically always return an empty list.

And that is because your method have already executed that print line (and the return statement) when you get the event over SignalR.

The callback you send into the hubConnection must have a way to report back to the UI, meaning it have to have a way to communicate back to the method that is calling fetchAnimals() WHEN the callback is executed.

So I'd inject the callback into fetchAnimals() as such:

typedef CallbackFunc = void Function(List<dynamic>? arguments);

Future<void> fetchAnimals(CallbackFunc callback) async {
....
  hubConnection.on('Animals', callback);
...
}
Related