Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use parent class of provided class #866

Closed
Jannik-dev opened this issue Mar 3, 2024 · 6 comments
Closed

Cannot use parent class of provided class #866

Jannik-dev opened this issue Mar 3, 2024 · 6 comments
Assignees
Labels
bug Something isn't working needs triage

Comments

@Jannik-dev
Copy link

Description
Hi, I have raised this issue in the bloc package and was delegated to provider (felangel/bloc#4077). I am encountering the following issue, when I provide a certain class and try to use subclasses in a bloc builder an ProviderNotFoundException is thrown.

Consider the following example:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class AbstractCubit<T> extends Cubit<T> {
  AbstractCubit(super.initialState);
}

class IntCubit extends AbstractCubit<int> {
  IntCubit() : super(0);

  void doStuff() {
    emit(1);
  }
}

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider<IntCubit>(
      create: (context) => IntCubit(),
      child: const MaterialApp(
        title: 'Flutter Demo',
        home: MyHomePage(),
      ),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: const BlocWidget<int>(),
    );
  }
}

class BlocWidget<T> extends StatelessWidget {
  const BlocWidget({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<AbstractCubit<T>, T>(
      builder: (BuildContext context, T state) {
        return const Text('test');
      },
    );
  }
}

Expected Behavior
The BlocBuilder<AbstractCubit, T> uses the provided IntCubit (since IntCubit is an AbstractCubit).

@Jannik-dev Jannik-dev added bug Something isn't working needs triage labels Mar 3, 2024
@rrousselGit
Copy link
Owner

Correct. This is unsupported.

If you wish for your object to be used with AbstractCubit instead of IntCubit, have your provider use AbstractCubit:

BlocProvider<AbstractCubit<int>>(

@Jannik-dev
Copy link
Author

Thanks for the quick reply, but simply providing AbstractCubit instead of IntCubit does not work, since I need the IntCubit functionality in another part of the app (in this example the doStuff method). But I don't want to use IntCubit in BlocWidget, because it does not need it.

My only idea right now is to provide IntCubit as AbstractCubit and as IntCubit but I dislike this approach too, because there could be more classes in the hierarchy.

@rrousselGit
Copy link
Owner

What you're asking is not possible in any case. You'll always have to write extra logic to support both context.watch<AbstractCubit<int>> and context.watch<IntCubit>

@Jannik-dev
Copy link
Author

Why cannot context.watch<AbstractCubit<int>> use the IntCubit? I mean, the IntCubit is an AbstractCubit<int>. Is there no simple way how I can use abstractions?

@rrousselGit
Copy link
Owner

That's not how InheritedWidgets work. They use exact type matching. There's no such thing as specifying a type, but getting a subclass instead. You have to manually expose your provider with said type. No way around it.

@Jannik-dev
Copy link
Author

Thank you very much for your explanation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage
Projects
None yet
Development

No branches or pull requests

2 participants