I have a void signup function and create account screen & I am using Nodejs backend & riverpod. I am struggling in implementing loading properly.
below is my auth_services.dart file
final authServicesProvider = Provider(
(ref) => AuthServices(),
);
class AuthServices {
void signupUser({
required BuildContext context,
required String email,
required String fullName,
required String password,
}) async {
try {
User user = User(
id: '',
name: fullName,
email: email,
countryCode: '',
phoneNumber: 0,
password: password,
type: '',
package: '',
token: '',
favorites: [],
);
http.Response res = await http.post(Uri.parse("$api/users/createaccount"),
body: user.toJson(),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Origin': '*',
});
httpErrorHandle(
response: res,
context: context,
onSuccess: () {
showSnackBar(
context: context,
content: "Account Created Successfully, You can now login",
msgType: 'success',
);
},
);
} catch (e) {
showSnackBar(context: context, content: e.toString(), msgType: 'error');
}
}
}
below is my auth_controller.dart file
final authControllerProvider = Provider(
(ref) {
final authServices = ref.watch(authServicesProvider);
return AuthController(authServices: authServices, ref: ref);
},
);
class AuthController {
final AuthServices authServices;
final ProviderRef ref;
AuthController({required this.authServices, required this.ref});
void createAccount(
BuildContext context,
String email,
String fullName,
String password,
) {
authServices.signupUser(
context: context,
email: email,
fullName: fullName,
password: password,
);
}
}
Below is my create_account_screen.dart file
class CreateAccountDesktopView extends ConsumerStatefulWidget {
const CreateAccountDesktopView({Key? key}) : super(key: key);
@override
ConsumerState<CreateAccountDesktopView> createState() =>
_CreateAccountDesktopViewState();
}
class _CreateAccountDesktopViewState
extends ConsumerState<CreateAccountDesktopView> {
final TextEditingController _fullnameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _confirmPasswordController =
TextEditingController();
@override
void dispose() {
super.dispose();
_fullnameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
}
void createAccountWithPassword() {
String userEmail = _emailController.text.trim();
String userPassword = _passwordController.text.trim();
String userConfirmPassword = _confirmPasswordController.text.trim();
if (userEmail.contains('@')) {
if (userEmail.isNotEmpty ||
_fullnameController.text.isNotEmpty ||
userPassword.isNotEmpty ||
userConfirmPassword.isNotEmpty) {
ref.read(authControllerProvider).createAccount(
context, userEmail, _fullnameController.text, userPassword);
} else {
showSnackBar(
context: context,
content: "All fields are required",
msgType: 'error');
}
} else {
showSnackBar(
context: context, content: "Invalid Email", msgType: 'error');
}
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
SizedBox(
width: deviceWidth(context) / 3,
height: deviceHeight(context),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 25,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Create An Account',
style: TextStyle(
color: blackColor,
fontSize: 25,
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(
height: 40,
),
SizedBox(
height: deviceHeight(context) * 0.045,
width: deviceWidth(context) * 0.2,
child: CustomIconButton(
icon: FontAwesomeIcons.google,
iconSize: 30,
btnColor: isOnWeb()
? mainPrimaryColor
: isDarkTheme(context)
? mainSecColorDark
: mainSecColor,
iconColor: whiteColor,
textColor: whiteColor,
onPressed: () {
// createUserAccountWithPassword();
},
text: 'Continue with google',
fontSize: deviceHeight(context) * 0.017,
),
),
const TextFieldTitle(title: 'Full Name'),
CustomTextField(
hintText: 'Enter your full name',
controller: _fullnameController,
),
const TextFieldTitle(title: 'Email Address'),
CustomTextField(
hintText: 'Enter your valid email address',
controller: _emailController,
),
const TextFieldTitle(title: 'Enter Password'),
CustomTextField(
hintText: 'Password',
controller: _passwordController,
),
const TextFieldTitle(title: 'Confirm Password'),
CustomTextField(
hintText: 'Confirm Password',
controller: _confirmPasswordController,
),
const SizedBox(
height: 25,
),
SizedBox(
height: deviceHeight(context) * 0.045,
width: deviceWidth(context) * 0.15,
child: CustomButton(
onPressed: createAccountWithPassword,
text: 'Create Account',
fontSize: deviceHeight(context) * 0.02,
),
),
const SizedBox(
height: 10,
),
RichText(
text: const TextSpan(
style: TextStyle(
fontSize: 14,
color: blackColor,
),
children: [
TextSpan(
text: "Already have an account? ",
),
TextSpan(
text: "Login",
style: TextStyle(
color: mainSecColor,
fontWeight: FontWeight.bold,
),
// recognizer: TapGestureRecognizer()
// ..onTap = () => Navigator.of(context)
// .pushNamedAndRemoveUntil(
// loginRoute, (route) => false),
),
],
),
),
],
),
)
],
),
);
}
}
I want to implement loading properly not by calling setState all over the files.