mobxjs / mobx.dart

MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.
https://mobx.netlify.app
MIT License
2.4k stars 310 forks source link

generated class is confused with dynamic type #775

Open dyardy opened 2 years ago

dyardy commented 2 years ago

After running flutter packages pub run build_runner build to generate code for mobx store I receive this error about dynamic type. I can resolve by changing the dynamic in the generated class to PostedImage how best to resolve this?

'_$PostedImageStore.postedImages' ('ObservableFuture<List>? Function()') isn't a valid override of '_PostedImageStore.postedImages' ('ObservableFuture<List>? Function()')

My store

part 'postedImage_store.g.dart';

class PostedImageStore = _PostedImageStore with _$PostedImageStore;

abstract class _PostedImageStore with Store {
  // repository instance
  late PostedImageRepository _repository;

  // store for handling errors
  final ErrorStore errorStore = ErrorStore();

  // constructor:---------------------------------------------------------------
  _PostedImageStore(PostedImageRepository repository) : this._repository = repository;

  @observable
  ObservableFuture<List<PostedImage>>? postedImages;

  // actions:-------------------------------------------------------------------
  @action
  Future getPostedImages() => postedImages = ObservableFuture(_repository.getPostedImages());

  @action
  Future<int> put(PostedImage postedImage) async {
    return _repository.insert(postedImage);
  }
}

In the generated file the error is coming from the dynamic type identified below. If I replace dynamic with PostedImage type then all is good. My PostedImage is a class is generated from a Drift/Moor class (see below)

 @override
  ObservableFuture<List<**dynamic**>>? get postedImages {
    _$postedImagesAtom.reportRead();
    return super.postedImages;
  }

  @override
  set postedImages(ObservableFuture<List<**dynamic**>>? value) {
    _$postedImagesAtom.reportWrite(value, super.postedImages, () {
      super.postedImages = value;
    });
  }
class PostedImage extends DataClass implements Insertable<PostedImage> {
  final int id;
  final String uid;
  final String emailAddress;
  final String description;
  PostedImage(
      {required this.id,
      required this.uid,
      required this.emailAddress,
      required this.description});
  factory PostedImage.fromData(Map<String, dynamic> data, {String? prefix}) {
    final effectivePrefix = prefix ?? '';
    return PostedImage(
      id: const IntType()
          .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
      uid: const StringType()
          .mapFromDatabaseResponse(data['${effectivePrefix}uid'])!,
      emailAddress: const StringType()
          .mapFromDatabaseResponse(data['${effectivePrefix}email_address'])!,
      description: const StringType()
          .mapFromDatabaseResponse(data['${effectivePrefix}description'])!,
    );
  }

I am using versions mobx: ^2.0.6+1 flutter_mobx: ^2.0.4

dyardy commented 2 years ago

I believe this has to do with the build order of the generated files. I am looking for a solution to this. Is there any way to order the file generation? (drift puts classes in {filename}_g.dart files and these are not discovered by mobx when it runs.

fzyzcjy commented 2 years ago

What about moving that custom type to a new file

dyardy commented 2 years ago

What about moving that custom type to a new file

That might work however, I would have to run the generator once for the drift/moor generation, then put the files in a new file name then re-run the generation for the mobx generator? (is this what u are suggesting?) The problem is around running the generator the 2nd time, as it probably would try to generate the drift/moor files once again and with same issue.

fzyzcjy commented 2 years ago

@dyardy No, I mean write down drift/moor-related code in a.dart and mobx-related code in b.dart. Is it possible?

washed commented 2 years ago

Hi, I am having the same issue also with drift generation Companion classes. I have confirmed that the order of file generation does not matter. Actually the drift/moor files are not being re-generated in my example (they have no changes). For me, drift and mobx code is already in different files.

washed commented 2 years ago

I have created an example project to demonstrate the behavior here: https://github.com/washed/mobx_codegen_dynamic_mwe In this example you can see how the type SomeModelCompanion (from database.g.dart) gets incorrectly generated with a return type of dynamic in the mobx store generated code.

Please let me know if i can help figure this out in any way. EDIT: I have added a "fake" generated code example by manually creating two files using the part and part of syntax (fake_gen.dart & fake_gen.g.dart) and here mobx code generation also fails to look up the types from the "generated" code. Is this maybe a more general issue with code generation where the analyzer doesn't follow the "part" files or something similar?

EDIT 2: This seems to be related https://github.com/mobxjs/mobx.dart/issues/246 and was closed without resolution.

andrelrf1 commented 1 year ago

I'm having this same problem, does anyone have any updates or solutions for this?