Reputation:
Hello I'm new to flutter, and I'm trying to do a simple user profile screen for a user who logged in but I stumbled in some errors, the first one was for when I tried to use the StreamBuilder() where the stream didn't get any data from the getter in the UserProvider()(that's where I putted my BL) it kept saying getCurrentUserData() was called on null, so i just connected it directly to the UserService() and it worked, but then when I tried to edit the user info and have the TextFormField() be filled with the user data, via the initState() and have the fullNameController get the data from the UserModel() the error returned it keeps saying fullName was called on null! how do I resolve this can anyone point on where I'm going wrong about here?
P.S I'm following this tutorial to build this.
My StreamBuilder() connected to UserProvider:
return StreamBuilder<UserModel>(
stream: userProviderData.getCurrentUserData(),
builder: (context, snapshot) {})
My StreamBuilder() directly connected to UserService:
Directly connected to UserService
return StreamBuilder<UserModel>(
stream: userService.getCurrentUser(),
builder: (context, snapshot) {})
UserService() class:
// Get User
Stream<UserModel> getCurrentUser() {
return _db.collection('users').doc(_auth.currentUser.uid).snapshots().map(
(user) => UserModel.fromJson(user.data()),
);
}
// Add or Update User info
Future<void> saveUser(UserModel user) {
final _options = SetOptions(merge: true);
return _db.collection('users').doc(user.userId).set(user.toMap(), _options);
}
UserProvider() class:
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return;
});
class UserProvider with ChangeNotifier {
final userService = UserService();
String _userId;
String _fullName;
// Getters
String get userId => _userId;
String get fullName => _fullName;
Stream<UserModel> get getCurrentUserData => userService.getCurrentUser();
// Setters
set changeFullName(String fullName) {
_fullName = fullName;
notifyListeners();
}
// Functions
void loadUser(UserModel userModel) {
_userId = userModel.userId;
_fullName = userModel.fullName;
}
void updateUser() {
final _currentUser = UserModel(
userId: _userId,
fullName: _fullName,
);
userService.saveUser(_currentUser);
}
}
EditProfileScreen():
class EditProfileScreen extends StatefulWidget {
const EditProfileScreen({this.userModel});
final UserModel userModel;
@override
_EditProfileScreenState createState() => _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final _fullNameController = TextEditingController();
final _validator = Validator();
@override
void dispose() {
_fullNameController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
final userStream = context.read(userProvider);
if (widget.userModel != null) {
// Edit
_fullNameController.text = widget.userModel.fullName;
userStream.loadUser(widget.userModel);
}
}
@override
Widget build(BuildContext context) {
final userData = context.read(userProvider);
return Scaffold(
body: Column(
children: [
TextFormFiled(
hintText: ‘Full name’,
keyboardType: TextInputType.name,
controller: _fullNameController,
validator: (value) => _validator.validateFullName(
value,
),
onChanged: (value) {
userData.changeFullName = value;
debugPrint(value);
}
),
ElevatedButton(
onPressed: () {
userData.updateUser();
Navigator.of(context).pop();
},
child: const Text(‘Save’),
),
],
),
);
}
}
Upvotes: 0
Views: 138
Reputation: 5601
Did you forget to return something?
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return; //return a UserProvider()
});
Upvotes: 1