aryehof / dart-eventsubscriber

A Flutter widget for subscribing to a Dart Event.
https://pub.dev/packages/eventsubscriber
Apache License 2.0
3 stars 0 forks source link

Error: "EventArgs" is not a subtype of type "TextEventArgs" #4

Open aryehof opened 1 month ago

aryehof commented 1 month ago
          Thanx for your great work but..

I ran into an issue with extended EventArgs.

A simple project:

import 'package:event/event.dart';
import 'package:eventsubscriber/eventsubscriber.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MainApp());
}

class TextEventArgs extends EventArgs {
  String text;
  TextEventArgs(this.text);
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {

  Event<TextEventArgs> event = Event<TextEventArgs>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              EventSubscriber(
                events: [ event ],
                builder: (context, status, args) {
                  return Text(args.text);
                }
              ),
              TextButton(
                onPressed: () => event.broadcast(TextEventArgs('Changed text')),
                child: const Text('Change text')
              )
            ],
          ),
        ),
      ),
    );
  }
}

Everything compiles fine but the initial loading breaks on eventsubscriber.dart:68 dart T _eventArgs = EventArgs() as T;

_TypeError (type "EventArgs" is not a subtype of type "TextEventArgs" in type cast)

In this example it's clear that there's no initial text property declared.

But in the earlier version the EventArgs in the builder function of EventSubscriber was optional so you could check for being null.

Am I doing something wrong here or?

Originally posted by @Sjonnie2nd in https://github.com/aryehof/dart-eventsubscriber/issues/2#issuecomment-2348940136

aryehof commented 1 month ago

@Sjonnie2nd Can reproduce this but it exposes a problem I'm thinking about how to best solve. Most likely the builder "args" parameter is going to need to be nullable, to handle the case of what to do when an Event hasn't occured yet, and hence there are no args.

Your initial ...

return Text(args.text);

is relying on an Event that hasn't happened yet. To solve this, making args nullable would changes and mean changing the line to something like...

return args != null ? Text(args.text) : Text("first text to display");

which is much less attractive.

This also brings complications with supporting multiple Events, which I might revert. Naming Events then becomes somewhat meaningless.

In the past I thought about not supporting arguments at all, because my intention was to really support an independent domain model.

class TestModel {
  String _text = "My Default Text";
  var textChanged = Event();

  void changeText(String newText) {
    _text = newText;
    textChanged.broadcast();
  }

  String get getText {
    return _text;
  }
}

...

  EventSubscriber(
      events: [tm.textChanged],
      builder: (context, status, args) {
        return Text(tm.getText);
      }),
  TextButton(
      onPressed: () => tm.changeText("boom"),
      child: const Text('Change text'))

In a traditional MVC architecture, the "view" isn't updated by passed data, but by observing a separate model. That perhaps is not what your trying to achieve?

Sjonnie2nd commented 1 month ago

Hi @aryehof , I must say personally I haven't any requirements. I ran into errors with using extended EventArgs, so I posted the issue.

But I can live with your thoughts of "not supporting arguments at all". In the passed days I adjusted my code, not working with extended EventArgs anymore and I even replaced all my implementations builder(context, status, args){} with builder: (_, __, ___){}. That is.. not using the passed arguments at all :)).