admin管理员组

文章数量:1356716

I'm currently learning Riverpod and trying to implement the MVVM (Model-View-ViewModel) pattern. I have a HomeModel that holds two lists (animalList and birdList), both fetched asynchronously. I am using a HomeViewModel to handle the fetching and updating of these lists.

Here is what I have so far:

@freezed
abstract class HomeModel with _$HomeModel { 
  const factory HomeModel({
    @Default(AsyncData([])) AsyncValue<List<Animal>> animalList, 
    @Default(AsyncData([])) AsyncValue<List<Bird>> birdList, 
  }) = _HomeModel;
}

ViewModel (HomeViewModel):

@riverpod
class HomeViewModel extends _$HomeViewModel  { 
  @override
  HomeModel build() { 
    return HomeModel();
  }

  // Fetch the list of animals and update the state accordingly
  Future<void> getAnimalList() async { 
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(animalList: AsyncLoading());
      final result = await repository.getAnimals();
      state = state.copyWith(animalList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(animalList: AsyncValue.error(e, stack));
    }
  }

  // Fetch the list of birds and update the state accordingly
  Future<void> getBirdsList() async { 
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(birdList: AsyncLoading());
      final result = await repository.getBirds();
      state = state.copyWith(birdList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(birdList: AsyncValue.error(e, stack));
    }
  }
}

The Issue:

In my HomeViewModel, I have two separate methods (getAnimalList() and getBirdsList()) to fetch data asynchronously. What I am stuck on is how to call both methods when the HomeViewModel is initialized. I want to make sure that both the animal and bird lists are fetched when the HomeViewModel is created, but I'm not sure how to trigger both methods in the initialization phase.

Here is what I tried:

  1. Calling both methods from the build function, but it seems I can't run async code directly in build().

I'm currently learning Riverpod and trying to implement the MVVM (Model-View-ViewModel) pattern. I have a HomeModel that holds two lists (animalList and birdList), both fetched asynchronously. I am using a HomeViewModel to handle the fetching and updating of these lists.

Here is what I have so far:

@freezed
abstract class HomeModel with _$HomeModel { 
  const factory HomeModel({
    @Default(AsyncData([])) AsyncValue<List<Animal>> animalList, 
    @Default(AsyncData([])) AsyncValue<List<Bird>> birdList, 
  }) = _HomeModel;
}

ViewModel (HomeViewModel):

@riverpod
class HomeViewModel extends _$HomeViewModel  { 
  @override
  HomeModel build() { 
    return HomeModel();
  }

  // Fetch the list of animals and update the state accordingly
  Future<void> getAnimalList() async { 
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(animalList: AsyncLoading());
      final result = await repository.getAnimals();
      state = state.copyWith(animalList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(animalList: AsyncValue.error(e, stack));
    }
  }

  // Fetch the list of birds and update the state accordingly
  Future<void> getBirdsList() async { 
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(birdList: AsyncLoading());
      final result = await repository.getBirds();
      state = state.copyWith(birdList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(birdList: AsyncValue.error(e, stack));
    }
  }
}

The Issue:

In my HomeViewModel, I have two separate methods (getAnimalList() and getBirdsList()) to fetch data asynchronously. What I am stuck on is how to call both methods when the HomeViewModel is initialized. I want to make sure that both the animal and bird lists are fetched when the HomeViewModel is created, but I'm not sure how to trigger both methods in the initialization phase.

Here is what I tried:

  1. Calling both methods from the build function, but it seems I can't run async code directly in build().
Share Improve this question asked Mar 31 at 4:35 Roy KruegerRoy Krueger 656 bronze badges 1
  • check Future.wait static method or wait extension property of Iterable – pskink Commented Mar 31 at 5:28
Add a comment  | 

1 Answer 1

Reset to default 0

You can simply change your build method to a future and run your codegen.

@riverpod
class HomeViewModel extends _$HomeViewModel  {
  @override
  Future<HomeModel> build() async {
    await getAnimalList();
    await getBirdsList();
    return HomeModel();
  }

  // Fetch the list of animals and update the state accordingly
  Future<void> getAnimalList() async {
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(animalList: AsyncLoading());
      final result = await repository.getAnimals();
      state = state.copyWith(animalList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(animalList: AsyncValue.error(e, stack));
    }
  }

  // Fetch the list of birds and update the state accordingly
  Future<void> getBirdsList() async {
    try {
      final repository = ref.read(repositoryProvider);
      state = state.copyWith(birdList: AsyncLoading());
      final result = await repository.getBirds();
      state = state.copyWith(birdList: AsyncData(result));
    } catch (e, stack) {
      state = state.copyWith(birdList: AsyncValue.error(e, stack));
    }
  }
}

本文标签: