1

My internship boss asked me to solve a problem which I am not being able to do so far. I have been given an ready application. This is basically flattered attendance app.

Now let me tell you clearly where I'm facing the issue.When the user click the student button,It takes the student to a class page,And in the class pledge the user or the student has to select the class by onTap event-One tapped and selected the class.the You, the user, goes to another page where the user will need to tap again to finally go to the check in Page-meaing another OnTap event./

Now my boss wants to get rid of the two OnTap events in the in between.He wants me to directly grow from student button to Student Item Page without losing the contents of the object that was passed. Please note I just show the important codes here scrapping the UI codes because it will become long.Please see if you can understand the codes.

The app uses bloc/statemanagement system.

Student Button-From here starts the flow(only important codes here)

final User user;
SelectUser({this.user});


Expanded(
 child: GestureDetector(
   onTap: () {
     final ClassroomRepository classroomRepository =
         ClassroomRepository(
       classroomApiClient: ClassroomApiClient(
         httpClient: http.Client(),
       ),
     );
     Navigator.push(
         context,
         MaterialPageRoute(
             builder: (context) => BlocProvider(
                   create: (context) => ClassroomBloc(
                       classroomRepository: classroomRepository),
                   child: ClassList(user: this.user),//user object is passed to the ClassList

                 )));

   },
   child: Image.asset('assets/logos/studentbutton.png'),
 )

The above is passing the user object to ClassList. Below is the full code for ClassList:

class ClassList extends StatelessWidget {
 final User user ;
 ClassList({this.user});
 @override
 Widget build(BuildContext context) {
   return Scaffold(

       body: Center(
         child: BlocBuilder<ClassroomBloc, ClassroomState>(
           builder: (context, state) {
             if (state is ClassroomEmpty) {
               print('load');
               BlocProvider.of<ClassroomBloc>(context)
                   .add(FetchClassroom(schoolId: this.user.id));
               return Center(child: Text('Please Wait'));
             } else if (state is ClassroomLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is ClassroomLoaded) {
               final classrooms = state.classrooms;
               return ListView.builder(
                 itemCount: classrooms.length,
                 itemBuilder: (context, position) {
                   return ClassItem(classroom: classrooms[position]);//GENERATES UI WITH ONTAP EVENT IN THE NEXT PAGE.
                 },
               );
             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

Now , it will go to Class ItemPage to perform the first onTap. You can see in the above code(return ClassItem(classroom: classrooms[position]) passing classroom object from repo)

Below is the full code for Class Item Page. HERE , I AM TRYING TO GET RID OF THIS ON TAP BUTTON WITHOUT LOSING THE CONTENT OF THE OBJECT THAT IS PASSED BUT FAILED REPEATEDLY.

import 'package:attendanceapp/blocs/student/blocs.dart';
import 'package:attendanceapp/repositories/student/repositories.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:attendanceapp/models/classroom.dart';
import 'package:attendanceapp/widgets/student/student.dart';
class ClassItem extends StatelessWidget {
 final Classroom classroom ;
 ClassItem({this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: (){
       final VisitorRepository studentRepository = VisitorRepository(
         visitorApiClient: StudentApiClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(context,
           MaterialPageRoute(builder: (context) =>
               BlocProvider(
                 create: (context) => StudentBloc(studentRepository:studentRepository),
                 child: Student(classroom: classroom),

               )
           )
       );
     },//tapping on the card
     child: Card(
         margin: EdgeInsets.all(20),
     child: Padding(
     padding: const EdgeInsets.all(20.0),
     child: Text(classroom.classroomName,style: TextStyle(fontSize: 30))
     )
     ),
   );
 }
}









From ClassItem Page , we go to the StudentPage passing ClassRooms as object.//Shows the Appbar and generates UI by returning the next page. Now this is the Page I don’t want to show but only pass the objects.



class Student extends StatelessWidget {
 final Classroom classroom ;
  Student({this.classroom});
 @override
 Widget build(BuildContext context) {

   return Scaffold(
       appBar: new AppBar(
         backgroundColor: Colors.amber[600],
         title: Text(classroom.classroomName),
       ),
       body:
       Center(

         child: BlocBuilder<StudentBloc, StudentState>(
           builder: (context, state) {
             if (state is StudentEmpty) {
               print(this.classroom);
               BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
               return Center(child: Text('Please Wait'));
             } else if (state is StudentLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is StudentLoaded) {
               final students = state.students;
               return ListView.builder(
                 itemCount: students.length,
                 itemBuilder: (context, position) {
                   return StudentItem(student:students[position], classroom: classroom,);
                 },
               );


             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

Finally, we go from StudentButton Page to StudeDetails Page. Below IS THE SECOND onTap in the studentItem page which I want to get rid. But failed …I want to go From Student Button Page to STUDENT ITEM PAGE without two OnTap evens and Not losing the content of the object. I have been trying for 7 days,but failed. I told my internship boss it is possible because each student has a class but he said do it any how.

Below is the next page we were talking about in the previous page. I just need to show StudentDetails page starting from studentButton without performing the two onTaps. I have struggling with this for about 7 days, but still couldn’t go from studentButton to studentDetails page skipping the intermittent pages.

class StudentItem extends StatelessWidget {
 final Student student;
 final Classroom classroom;
 StudentItem({this.student, this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: () {
       final StudentAttendanceRepository attendanceRepository =
           StudentAttendanceRepository(
         studentAttendanceClient: StudentAttendanceClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(
           context,
           MaterialPageRoute(
             settings: RouteSettings(name: '/studentDetail'),
             builder: (context) => BlocProvider(
               create: (context) => StudentAttendanceBloc(studentAttendanceRepository: attendanceRepository),
               child: StudentDetail(student: student,),
             ),
           ),
       ).then((value){
         if(value){
           BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
         }
       });
     },

////UI CODES HERE…NOT PASTED HERE BECAUSE TOO LONG
    }

1 Answers1

0

So to access the data on different pages, you can pass the data to your event from page 1 and then in the bloc, you can assign this data to one of the state class. Now on page 2 or page 3, wherever you want to access the data, you can use BlocListener or BlocBuilder and access the data using the state object.

Abhishek Doshi
  • 465
  • 2
  • 5
  • i tried that, but getting error-maybe due to my lack of understanding of the bloc..Any simple solution in the light of this code? – Habeeb E Sadeed Mar 31 '22 at 18:16