-2

I am programming a flutter Gym App, I am saving every program for everyday in a dart file, the programs are in order with an item id which is written like for ex: Week1Day1, Week1Day2...

the same time I am using Firebase Firestore to save the week and the day, it works fine no problem.

My problem is when I want to get week and day from firestore, it is future value so I need to do everything inside .then() and this is only for local variable ..and outside of .then() my return does not know this value.

Another thing is I can't use the async and await because it shows me an error:

A value of type 'Future<List<WorkoutData>>' can't be assigned to a variable of type 'List<WorkoutData>'.

check the code please.

using async await

class WorkoutsBloc extends Bloc<WorkoutsEvent, WorkoutsState> {
  WorkoutsBloc() : super(WorkoutsInitial());

List<WorkoutData> workouts= initialiseWorkoutList();



  @override
  Stream<WorkoutsState> mapEventToState(WorkoutsEvent event,) async* {
        if (event is WorkoutsInitialEvent) {
      GlobalConstants.workouts = await DataService.getWorkoutsForUser();
      for (int i = 0; i < workouts.length; i++) {
        final workoutsUserIndex =
        GlobalConstants.workouts.indexWhere((w) => w.id == workouts[i].id);
        if (workoutsUserIndex != -1) {
          workouts[i] = GlobalConstants.workouts[workoutsUserIndex];
        }
      }
      yield ReloadWorkoutsState(workouts: workouts);
    } else if (event is CardTappedEvent) {
      yield CardTappedState(workout: event.workout);
    }
  }


}


Future<String?> getWeek() async {
  FirebaseAuth auth=FirebaseAuth.instance;
  var userID=auth.currentUser?.uid;
  var collection = FirebaseFirestore.instance.collection("users");
  var docSnapshot = await collection.doc(userID.toString()).get();
  Map<String, dynamic>? data = docSnapshot.data();

  var weekNum = await data?["weekNumber"].toString();

  return Future(() => weekNum);

}

Future<String?> getDay() async {
  FirebaseAuth auth=FirebaseAuth.instance;
  var userID=auth.currentUser?.uid;
  var collection = FirebaseFirestore.instance.collection("users");
  var docSnapshot = await collection.doc(userID.toString()).get();
  Map<String, dynamic>? data = docSnapshot.data();

  var dayNum = await data?["dayInWeek"].toString();

  return Future.value(dayNum);

}


Future<List<WorkoutData>> initialiseWorkoutList() async{
var week=await getWeek();
var day=await getDay();
  List<WorkoutData> workouts = DataConstants.workouts
      .where((element) => element.id!.contains("Week${week}Day${day}"))
      .toList();

  workouts.addAll(DataConstants.homeWorkouts);

  return workouts;

  }

if I do inside "mapEventToState" call final myWorkouts = await workouts; and of course List<WorkoutData> workouts has to be Future<List<WorkoutData>> workouts, errors got it in other files

check this out:

 class WorkoutContent extends StatelessWidget {
  WorkoutContent({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: ColorConstants.homeBackgroundColor,
      height: double.infinity,
      width: double.infinity,
      child: _createHomeBody(context),
    );
  }

  Widget _createHomeBody(BuildContext context)  {
    final bloc = BlocProvider.of<WorkoutsBloc>(context);

    return BlocBuilder<WorkoutsBloc, WorkoutsState>(
        buildWhen: (_, currState) => currState is ReloadWorkoutsState,
        builder: (context, state) {
          return Padding(
            padding: const EdgeInsets.only(top: 50),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 20.0),
                  child: Text(
                    TextConstants.workouts,
                    style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                  ),
                ),
                const SizedBox(height: 5),
                Expanded(
                  child: ListView(
                    children:
                    bloc.workouts.map((e) => _createWorkoutCard(e)).toList(),
                  ),
                ),
              ],
          ),
          );
       },
    );
  }

  Widget _createWorkoutCard(WorkoutData workoutData) {

    return Padding(
      padding: const EdgeInsets.only(bottom: 20),
      child: WorkoutCard(workout: workoutData),
    );
  }
}

the error is in: bloc.workouts.map((e) => _createWorkoutCard(e)).toList(),

The method 'map' isn't defined for the type 'Future'.
MohBoudraa
  • 13
  • 3
  • inside `mapEventToState` call `final myWorkouts = await workouts;` and of course `List workouts` has to be `Future> workouts` – pskink Mar 07 '23 at 15:28
  • @pskink thank you sir, but I got errors in other pages like: ` bloc.workouts.map((e) => _createWorkoutCard(e)).toList()` `The method 'map' isn't defined for the type 'Future'.` – MohBoudraa Mar 07 '23 at 16:00

1 Answers1

0

You're doing wrong with the return of value

Future<String?> getWeek() async {
  .....

  return Future(() => weekNum);

}

Future<String?> getDay() async {
  ....

  return Future.value(dayNum);

}

You need to replace return values like this.

Future<String?> getWeek() async {
      .....
    
      return weekNum;
    
    }
    
    Future<String?> getDay() async {
      ....
    
      return dayNum;
    
    }
Rohan Jariwala
  • 1,564
  • 2
  • 7
  • 24