Can't pass in a subtype of an abstract class as argument into a function

397

After copy pasting the code here and checking for completeness I found the issue. For anyone facing the same: the import of the event within the bloc code contains two /'s within the path. After removing one / the compiler didn't complain anymore that the wrong type is being passed. No idea how this second / was added and why the compiler didn't complain at all about that. Apparently, the objects defined in ..//event.dart are not the same when imported from ../event.dart

Share:
397
Martin Nowosad
Author by

Martin Nowosad

I'm a freelance software developer with focus on Android and Backend development. My favorite programming languages are Python, Kotlin and TypeScript. I worked for 8 years with Java and I don't like that programming language anymore after having worked heavily with Kotlin. I like the frameworks Django, Flask, React (+ React Native) and Flutter (I'm not very experienced with Dart, though). Besides that I like reading and thinking about software architecture backend- and client-wise. Stack Overflow is great because I can not only share my experience but also learn a lot. If you can not explain something then you probably do not understand it

Updated on December 28, 2022

Comments

  • Martin Nowosad
    Martin Nowosad over 1 year

    I followed the BloC tutorial and did according to them, I have a Bloc which has this method

      @override Stream<FridgeState> mapEventToState(FridgeEvent event) async* { .. }
    

    where FridgeEvent is an abstract class

    abstract class FridgeEvent {
      const FridgeEvent();
    }
    
    class CreateFridgeEvent extends FridgeEvent {
      final double lat, lng;
    
      CreateFridgeEvent({required this.lat, required this.lng});
    }
    
    class DeleteFridgeEvent extends FridgeEvent {}
    

    When instantiating the bloc within the widget and passing in a subclass of FridgeEvent, I get an error that the parameter type can't be assigned. What am I doing wrong?

    enter image description here

    Upon request, here's the code of the bloc

    import 'package:flutter_bloc/flutter_bloc.dart';
    import 'package:foodey_flutter/domain/fridge/entity/Fridge.dart';
    import 'package:foodey_flutter/domain/fridge/usecase/CreateFridgeUseCase.dart';
    import 'package:foodey_flutter/factory/FridgeFactory.dart';
    import 'package:foodey_flutter/ui/fridge/create//event.dart';
    import 'package:foodey_flutter/ui/fridge/create//state.dart';
    
    class FridgeBloc extends Bloc<FridgeEvent, FridgeState> {
      CreateFridgeUseCase? createFridgeUseCase;
    
      FridgeBloc(FridgeState initialState) : super(initialState) {
        FridgeFactory.inject(this);
      }
    
      @override
      Stream<FridgeState> mapEventToState(FridgeEvent event) async* {
        if (event is CreateFridgeEvent) {
          Fridge? result = await createFridgeUseCase?.execute(event.lat, event.lng);
          if (result != null)
            yield FridgeSuccessfullyLoadedState(result);
          else
            yield FridgeErrorState(
                exception: Exception("Failed to create a fridge"));
        } else {
          yield FridgeErrorState(exception: Exception("Operation not supported"));
        }
      }
    }
    

    Here's the code of the widget

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    import 'package:foodey_flutter/ui/fridge/create/FridgeBloc.dart';
    import 'package:foodey_flutter/ui/fridge/create/event.dart';
    
    class CreateFridgeWidget extends StatefulWidget {
      @override
      _CreateFridgeState createState() => _CreateFridgeState();
    }
    
    class _CreateFridgeState extends State<CreateFridgeWidget> {
      late FridgeBloc _bloc;
    
      @override
      void initState() {
        super.initState();
        this._bloc = BlocProvider.of<FridgeBloc>(context);
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          key: widget.key,
          alignment: Alignment.center,
          padding: EdgeInsets.all(8),
          child: Column(
            children: [
              Text("Are you sure you want to create your fridge?"),
              Row(
                children: [
                  TextButton(
                    key: widget.key,
                    onPressed: () {
                      _bloc.add(CreateFridgeEvent(lat: 0, lng: 1));
                    },
                    child: Text("Yes"),
                  ),
                  TextButton(
                    key: widget.key,
                    onPressed: () => {},
                    child: Text("No"),
                  ),
                ],
              )
            ],
          ),
        );
      }
    }
    

    And here are my defined events

    abstract class FridgeEvent {
      const FridgeEvent();
    }
    
    class CreateFridgeEvent extends FridgeEvent {
      final double lat, lng;
    
      CreateFridgeEvent({required this.lat, required this.lng});
    }
    
    class DeleteFridgeEvent extends FridgeEvent {}
    

    Update: After copy pasting the code here and checking for completeness I found the issue. For anyone facing the same: the import of the event within the bloc code contains two /'s within the path. After removing one / the compiler didn't complain anymore that the wrong type is being passed. No idea how this second / was added and why the compiler didn't complain at all about that. Apparently, the objects defined in ..//event.dart are not the same when imported from ../event.dart

    • Kirill Bubochkin
      Kirill Bubochkin about 3 years
      Can be a problem with imports. Can you share your bloc file and widget file (full code with imports)?
    • nvoigt
      nvoigt about 3 years
      Pleas provide a minimal reproducible example.
    • Martin Nowosad
      Martin Nowosad about 3 years
      updated, thanks for the hint