part 'vendor_detailscontroller.g.dart';
@injectable
class VendorDetailsController extends VendorDetailsControllerBase with $VendorDetailsController{
VendorDetailsController(super.logger);
}
abstract class VendorDetailsControllerBase extends BaseController with Store,FormMixin{
I am trying to submit the form so the value of isLoading would become true and showing a circular progress indicator instead of the button in the following widget
I have this base controller I usually use to extend all my controllers
`import 'package:mobx/mobx.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/snakebars/bottom_snack_bar.dart'; import 'package:wow_vir_admin_dashboard/core/utils/enums.dart'; import 'package:wow_vir_admin_dashboard/data/errors/core_errors.dart'; import 'package:wow_vir_admin_dashboard/data/errors/custom_error.dart'; import 'package:wow_vir_admin_dashboard/data/repositories/abstract/i_logger.dart';
part 'base_controller.g.dart';
class BaseController extends BaseControllerBase with _$BaseController{ BaseController(super.logger); }
abstract class BaseControllerBase with Store {
final ILogger logger;
BaseControllerBase(this.logger);
@observable CustomError? error;
@observable bool isLoading=false;
@action Future onInit()async{}
@action void dispose(){}
@action Future runStorePrimaryFunction(final Future function, {final void Function(CustomError)? onCatchError })async{
try{
if(isLoading||error!=null) {
return false;
}
}
}`
for every form in my application I use a mixin to provide form functionality `
import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; import 'package:wow_vir_admin_dashboard/core/controllers/base_controller.dart'; import 'package:wow_vir_admin_dashboard/data/errors/api_error_model.dart';
mixin FormMixin on BaseController{ final GlobalKey formKey = GlobalKey();
Future submitFunction() ;
Future afterSuccessSubmitting() ;
List focusNodes=[];
void initForm({required final int fieldsNumber,final Map<String,String?>? initialValues}){ currentValues=ObservableMap.of(initialValues??{}); focusNodes=ObservableList.of(List.generate(fieldsNumber, (final index) =>FocusNode() )); }
@observable ObservableMap<String,String?> currentValues=ObservableMap();
@observable ObservableMap<String,String> validationErrors=ObservableMap();
@action void changeFormValue(final String fieldKey,final String? newValue)=> currentValues[fieldKey]=newValue;
@computed bool get canSubmit=> formKey.currentState!.validate();
@action Future submitForm()=>runStoreSecondaryFunction(Future(()async{
if(isLoading || !canSubmit){
return;
}
} ),onCatchError: (final e){ isLoading=false; if(e is ApiErrorModel) { validationErrors=ObservableMap.of( e.validationErrors); } });
@override void dispose(){ for (var element in focusNodes) { element.dispose(); } } } `
and I extend it with my VendorDetailsController class
`
import 'package:injectable/injectable.dart'; import 'package:mobx/mobx.dart'; import 'package:wow_vir_admin_dashboard/core/controllers/base_controller.dart'; import 'package:wow_vir_admin_dashboard/core/controllers/controllers_mixins/form_mixin.dart'; import 'package:wow_vir_admin_dashboard/core/utils/enums.dart'; import 'package:wow_vir_admin_dashboard/data/errors/core_errors.dart';
part 'vendor_detailscontroller.g.dart'; @injectable class VendorDetailsController extends VendorDetailsControllerBase with $VendorDetailsController{ VendorDetailsController(super.logger);
}
abstract class VendorDetailsControllerBase extends BaseController with Store,FormMixin{
VendorDetailsControllerBase(super.logger){ initForm(fieldsNumber: 8); }
@override Future afterSuccessSubmitting()async {
await Future.delayed(Duration(seconds: 10));
print('Ended');
}
@override Future submitFunction() async{
print('WISO HERE');
/if(currentValues['wowVirDeliveryCommission']==null &¤tValues['vendorDeliveryCommission']==null )
throw NotSelectedError(fieldName: 'Commission');/
}
}`
I am trying to submit the form so the value of isLoading would become true and showing a circular progress indicator instead of the button in the following widget
`import 'dart:ui';
import 'package:auto_route/annotations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/validators/is_not_empty_validator.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/widgets/custom_app_bar.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/widgets/custom_sized_box.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/widgets/main_button.dart'; import 'package:wow_vir_admin_dashboard/core/presentation/widgets/text_fields/form_controller_text_field.dart'; import 'package:wow_vir_admin_dashboard/dependencies.dart'; import 'package:wow_vir_admin_dashboard/features/vendors/controllers/vendor_details_controller.dart';
@RoutePage() class VendorDetailsPage extends StatefulWidget {
const VendorDetailsPage({Key? key, }) : super(key: key);
@override State createState() => _VendorDetailsPageState();
}
class _VendorDetailsPageState extends State {
late VendorDetailsController controller;
@override void initState() { controller = getIt(param1:null);
super.initState();
}
@override Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( context: context, barTitle: 'Vendor details', ), body: Form( key: controller.formKey, child: SingleChildScrollView( padding: EdgeInsets.all( 32.r), child: Column( children: [
}
@override void dispose() { controller.dispose(); super.dispose(); } } `
it prints that isLoading=false and in the controller isLoading =true ! the same code would work perfectly with mobile apps