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'.
> workouts`