Closed davidAg9 closed 4 years ago
also I am using bloc 5.0.0 and flutter_bloc 5.0.0 since I am not yet familiar with cubit and bloc 6.0.0
Hi @davidAg9 👋 Thanks for opening an issue!
Can you verify that you only have a single instance of the bloc? I'm guessing you are creating multiple instances of the bloc and so the listener is listening to a different instance than the one you are interacting with. If that doesn't help, could you please provide a link to a sample app which reproduces the issue? Thanks 👍
What exactly do you mean by instance of bloc ; do you mean create an bloc provider in on screen/ wigdet and creating another provider in a widget below it in another screen down the previous widget with the same bloc?
I have invited to the repo to have a look at the issue
`import 'dart:io';
import 'package:date_format/date_format.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flushbar/flushbar.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:image_picker/image_picker.dart'; import 'package:rokcare/bloc/patient_register_bloc/patient_registration_bloc.dart'; import 'package:rokcare/models/patient.dart'; import 'package:rokcare/repositories/firebase/storage.dart';
import 'components/bloodtypeDrop.dart';
class PatientForm extends StatefulWidget { @override _PatientFormState createState() => _PatientFormState(); }
class _PatientFormState extends State
String _img = '';
final picker = ImagePicker();
bool male = false;
bool female = false;
DateTime _selectedDate = DateTime.now();
String _selectedsex = '';
int index = 0;
bool photoLoading = false;
Patient pat = Patient();
@override
Widget build(BuildContext context) {
final String formatDob = formatDate(_selectedDate, [yyyy, '-', M, '-', dd]);
return BlocProvider(
create: (BuildContext context) => PatientRegistrationBloc(),
child: BlocBuilder<PatientRegistrationBloc, PatientRegistrationState>(
builder: (context, state) => SafeArea(
child: DefaultTabController(
initialIndex: index,
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text(
'Medical Form',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
bottom: TabBar(tabs:
pat.info.sex = _selectedsex;
});
},
child: Container(
decoration: BoxDecoration(
color: male
? Colors.teal[500]
: Colors.grey[300],
borderRadius: BorderRadius.all(
Radius.circular(30))),
height: 60,
width: 120,
child: Center(
child: Text(
'Male',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
)),
),
),
SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
setState(() {
male = false;
female = true;
_selectedsex = 'female';
pat.info.sex = _selectedsex;
});
},
child: Container(
decoration: BoxDecoration(
color: female
? Colors.teal[500]
: Colors.grey[300],
borderRadius: BorderRadius.all(
Radius.circular(30))),
height: 60,
width: 140,
child: Center(
child: Text(
'Female',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
)),
),
),
],
),
],
),
),
),
),
),
Container(
height: 100,
child: Form(
onChanged: () => _patientFormKey.currentState.save(),
key: _patientFormKey,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Address 1',
border: OutlineInputBorder()),
onSaved: (value) =>
pat.info.contactInfo.addressLine = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
decoration: InputDecoration(
labelText: 'Address 2',
border: OutlineInputBorder(),
),
onSaved: (value) =>
pat.info.contactInfo.addressLine2 = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
decoration: InputDecoration(
labelText: 'City',
hintText: 'Accra',
border: OutlineInputBorder()),
onSaved: (value) =>
pat.info.contactInfo.city = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Region',
hintText: 'Greater Accra',
border: OutlineInputBorder()),
onSaved: (value) =>
pat.info.contactInfo.state = value,
),
],
),
),
),
),
),
Container(
height: 580,
child: Form(
key: _medicalInfoFormKey,
onChanged: () => _medicalInfoFormKey.currentState.save(),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: <Widget>[
SizedBox(
height: 10,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(),
image: DecorationImage(
image: NetworkImage(_img ??
'http://www.european-athletics.org/imgml/athletes/man-placeholder.jpg'),
)),
height: 86,
width: 102,
child: Stack(children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
vertical: 1, horizontal: 1),
child: Align(
alignment: Alignment.bottomRight,
child: GestureDetector(
onTap: () async {
setState(() {
photoLoading = true;
});
await getImage()
.then((value) => this.setState(() {
photoLoading = false;
}));
},
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20),
color: Colors.blue,
),
width: 32,
height: 38,
child: Center(
child: Icon(
Icons.add_a_photo,
color: Colors.white,
),
),
),
),
),
),
]),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: photoLoading
? CircularProgressIndicator()
: Text(
'Select a Passport picture',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
Align(
alignment: Alignment.center,
child: BloodType(
patientBlood: pat.medicalInfo.bloodtype),
),
SizedBox(
height: 10.0,
),
TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Height(cm)',
border: OutlineInputBorder()),
onSaved: (value) =>
pat.medicalInfo.height = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Weight(kg)',
border: OutlineInputBorder()),
onSaved: (value) =>
pat.medicalInfo.weight = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'Emergency Contact',
border: OutlineInputBorder(),
),
onSaved: (value) =>
pat.emergencyContact.number = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
decoration: InputDecoration(
labelText: 'Emergency Contact name',
border: OutlineInputBorder(),
),
onSaved: (value) =>
pat.emergencyContact.name = value,
),
SizedBox(
height: 10.0,
),
TextFormField(
decoration: InputDecoration(
labelText: 'Emergency Contact Relationship',
border: OutlineInputBorder(),
),
onSaved: (value) =>
pat.emergencyContact.relation = value,
),
SizedBox(
height: 16,
),
BlocListener<PatientRegistrationBloc,
PatientRegistrationState>(
listener: (context, state) {
if (state is PFinishingRegistration)
return CircularProgressIndicator();
else if (state
is PRegistrationFinalizationFailure)
return Flushbar(
title: 'REGISTRATION FAILED',
message: 'Unable to Finish Registration',
icon: Icon(
Icons.warning,
color: Colors.red,
),
duration: Duration(seconds: 4),
backgroundGradient: LinearGradient(
colors: [Colors.white70, Colors.teal]),
);
else if (state is PFinishedRegistration)
return Navigator.of(context)
.popAndPushNamed('/patientDashBoard');
},
child: GestureDetector(
onTap: () {
BlocProvider.of<PatientRegistrationBloc>(
context)
..add(PFinishRegistration(patient: pat));
},
child: Align(
alignment: Alignment.centerRight,
child: Container(
decoration: BoxDecoration(
color: Colors.teal[300],
borderRadius: BorderRadius.all(
Radius.circular(30))),
height: 60,
width: 120,
child: Center(
child: Text(
'ENROLL',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
)),
),
),
),
),
],
),
),
),
),
),
]),
),
),
),
),
);
}
androidDate(BuildContext context) async { showDatePicker( initialDate: DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime.now(), context: context, initialEntryMode: DatePickerEntryMode.calendar, ).then((value) { this.setState(() { _selectedDate = value; pat.info.dob = value; }); }); }
iosDate(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext builder) { return Container( height: MediaQuery.of(context).copyWith().size.height, color: Colors.white, child: Column( children: [ Flexible( child: CupertinoDatePicker( mode: CupertinoDatePickerMode.date, onDateTimeChanged: (picked) { if (picked != null && picked != _selectedDate) setState(() { _selectedDate = picked; pat.info.dob = picked; }); }, initialDateTime: _selectedDate, minimumYear: 1900, maximumYear: DateTime.now().year, ), ), FlatButton( child: Text('Done'), onPressed: () => Navigator.pop(context), color: Colors.green, ), ], ), ); }); }
Future getImage() async { photoLoading = true; File docImg = await FilePicker.getFile(type: FileType.image);
StorageRepository img = StorageRepository();
img
.saveFile(docImg, StoragePaths.Avatars)
.then((value) => this.setState(() {
_img = value;
pat.info.photoUrl = value;
photoLoading = false;
}));
} } `
Hi @davidAg9 👋
Your code is incomplete and really hard for anyone to get it in a run-able state. Please create a minimal reproduction repository with your issue and share a link to it so we could run it locally 👍
I have gone through and I sent only the widget of where the listener was implemented Do you want to to see how I implanted the bloc itself before implementation in the above widget ?,I have though given access to the repo to @felangel for review .
Still waiting for response ,if you need help navigating to the bloc and the where the error appears to occurs please lemme know @felangel
Hi @davidAg9 I took a look and the issue is you are creating two different instances of the PatientRegistrationBloc
This means that the bloc that you are listening on is different from the bloc you are adding the events to. Please make sure to have a single instance of the bloc which you are adding events and consuming.
Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 👍
thank you will take a look at it and give you a response
you know its because of your overall character and commitment to the quality of your product that makes it so good .I am personally impressed and will be loyal to bloc as I believe its the best state management for flutter and should be implemented in other frameworks like django and the likes .
this is what happens if I take the patientregistrationBloc implementation from the PatientSignup widget. I thought bloc works by a tree order so theoretically it should work since PatientSignUp widget is one level above the PatientForm so I don't get why it cannot find the instance because in learning the bloc I understood that once a bloc provider is instantiated any widget below where the bloc was instantiated can use that bloc .if that is not the case please enlighten me .(how then will a bloc be scope or global if I am having such behaviour in my project)
this is how I wrote it
It I believe I have unraveled the issue ,so the issue is from a Firebase document its checking and of which its returning null which in turn throws an exception and does not allow the listener to execute tho I don't understand why the failed state to did not execute I am attempting to fix the issue with firebase to see If it will respond
Glad to hear you found the problem! What was the exception and how are you planning to address it?
I implemented a Bloclistener on a button that calls a Finished registration event which save the patient to firebase and some of the fields to sembast(local database ) but after the event is dispatch in debug mode I see the state are emmitted but it seem the listener is not reacting to any of response declared nothing happens on the UI