flvm 0.0.2 copy "flvm: ^0.0.2" to clipboard
flvm: ^0.0.2 copied to clipboard

flvm mvvm package extension

flvm based on Flutter Architecture case study and Compass App example.

Additionally added base classes to aviod boilerplate code and improved error handlings.

Basic usage #

Create a View Model:

class MyViewModel extends FlVm {

Don`t forget to call notifyListeners() when you need to deliver updated:

 void increment() {
    _counter++;
    notifyListeners();
  }

Inherit your widget state from FlVmState:

class _MyScreenState extends
FlVmWidget<MainScreen, MyViewModel> {

Bind your View Model:

 @override
  MyViewModel bindViewModel() => MyViewModel();

Use viewModelBuilder to listen for View Model updates:

viewModelBuilder<MainViewModel>(
              builder: (context, vm) {
                return Text(
                  '${vm.counter}',
                  style: Theme.of(context).textTheme.headlineMedium,
                );
              },
            ),

Advanced setup #

Error handling #

Additionally use can use onError function to handle errors you emit in View Model. Add onError function to your widget state class:

  void onError(Exception error) {
  		super.onError(error);
  		//show error dialog here
  }

Call setError in your View Model to emit an error:

 setError(Exception('Ooops...'));

Commands #

Create a new Command in your View Model:

late Command1 login;

...

login = Command1<void, (String username, String password)>(
      _login,
      onError: _onCommandError, //optional
    );

Create body function for your Command:

Future<Result<void>> _login((String, String) credentials) async {
    await Future.delayed(const Duration(milliseconds: 500));
    return Result.ok(null);
  }

Also you can set optional onError param to handle Command errors and deliver them to UI using setError:

onError: _onCommandError,
void _onCommandError(Exception error) {
    setError(error);
  }

In your Widget execute command where you need:

viewModel.login.execute((
      _usernameController.text,
      _passwordController.text,
    ));

Use commandBuilder to handle Command state in widget tree:

commandBuilder<void>(
                command: viewModel.login,
                builder: (context, command) {
                  return ElevatedButton(
                    onPressed: _onLogin,
                    child: command.running
                        ? const CircularProgressIndicator()
                        : Text('LOGIN'),
                  );
                },
              ),

Use listener to listen to command updates outside the widget tree:

 @override
  void onVmInitialized() {
    super.onVmInitialized();
    viewModel.login.addListener(_onLoginResult);
  }

  @override
  void didUpdateWidget(covariant LoginScreen oldWidget) {
    super.didUpdateWidget(oldWidget);
    viewModel.login.updateListener(_onLoginResult);
  }

  @override
  void dispose() {
    super.dispose();
    viewModel.login.removeListener(_onLoginResult);
  }
void _onLoginResult() {
    if (viewModel.login.isOk) {
      viewModel.login.clearResult();
      Navigator.of(
        context,
      ).pushReplacement(MaterialPageRoute(builder: (context) => MainScreen()));
    }

    ///on error do nothing
  }
1
likes
150
points
32
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

flvm mvvm package extension

Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

flutter

More

Packages that depend on flvm