lazx

Last updated:

0 purchases

lazx Image
lazx Images
Add to Cart

Description:

lazx

Lazx #
A state management library based on the ViewModel design pattern for Flutter.
From a lazy dev for lazy devs. 🥱
Index #

Introduction
Usage
Examples
Motivation
Contributing
Articles & Videos
Dart Version
Maintainers
FAQ

Introduction #
Lazx is a state-management library that makes it easy to handle reactive data, from your UI without having to think about how you will do it.
It's based on the MVVM design pattern and allows you to implement it in the easiest possible way.
You will not have to handle many files, inherit many classes or think about the best way to implement it, everything is done in a way that you just have to think about the logic and UI of your app, nothing more (and nothing less, I can't make your app for you 🤷‍♂️).
Enough talking let's jump into the concrete things 👇
Usage #
Lazx can be used in many ways and has been made so it can be adapted depending the situation you're facing.
Everything is based around the use of the Lazx Widgets/Builders but before, you should understand the easy concept of... MVVM applied with Lazx.
MVVM with Lazx #
Intro : Lazx State
Everything is about state in Flutter which is not necessarly the case in other languages/platforms. For these reason, I've added the managment of state inside the data so it can be synced with the state of your views.
I've determined 4 main states :

Initial - Represent the default state for a data. Could be before a loading/success/error flow, or just the one default state. By default, every data/view will starts with this state.
Loading - Represent a loading state for the data, if applicable.
Success - Represent a success state for a data. Could also be for a loaded data.
Error - Represent an error state for a data, if applicable.

The Model : Lazx Data
For those comming from the Android world a LazxData is a simple version of LiveData adapter to Flutter with a state managment.
For the other, it's a way to subscribe and listen to the changes of your data and introduce a state to it.
// Initialize your data
LazxData<int> counter = LazxData<int>(0);

// Access the current value
final currentValue = counter.value;

// Update the value/state
counter.push(counter.value + 1);
counter.push(-1, lxState: LxState.Error);
counter.setState(LxState.Loading);

// Listen to value/state changes
counter.stream.listen((value) {
print(value);
});

counter.state.listen((state) {
print(state);
});
copied to clipboard
LazxData are made to be used inside view models 👇
Lazx View Model - The View Model
A view model is simply a class that will be linked to a view and hold its data.
A LazxViewModel is exactly that, with the addition that your data are LazxData objects and you should declare them.

You can totally use a LazxViewModel wihtout using LazxData's.

class SimpleDemoViewModel extends LazxViewModel {
LazxData<int> counter = LazxData<int>(0);

@override
List<LazxData> get props => [counter];

void increment() {
counter.push(counter.value + 1);
}
}
copied to clipboard
The props getter is used to dispose all your LazxData listeners when the view model is disposed... at the same time that the view it's linked to.
The view model should be linked to a view, the Lazx Screen 👇
Lazx Screen View - The View
The view will be linked to only one view model.
I've called a view LazxScreen LazxView as usually, a there's a view model per screen, so you should use the LazxView on a widget that represent a screen for your app.

Of course, you can totally use a LazxView for a portion of your screen (also known as Fragment in Android)

class LxDemoScreen extends LazxView<SimpleDemoViewModel> {
@override
SimpleDemoViewModel getViewModel() => SimpleDemoViewModel();

@override
Widget build(BuildContext context, SimpleDemoViewModel viewModel) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Lazx Screen Demo'),
),
body: Center(
child: Text('Too Lazx'),
),
);
}
}
copied to clipboard
The function getViewModel() should be overrided to provide the view model of your screen. The viewModel will then be linked to your screen view.
The build function will be a bit different en give you access directly to your view Model.
You can of course access your view model in other Widgets down in the tree of you LazxScreen by using :
// Access view model from any widget down in the sub tree
viewModel<SimpleDemoViewModel>(context).doSomething();
copied to clipboard
Lazx Useful classes #
I've added some classes to make the possibility to build big apps easier and match most of the use cases you will encounter.
Lazx State
The Lazx State is almost the same as a Lazx Data, the only difference is that there's no data, juste a state to listen.
This could be useful when you only need a state for something that doesn't necessarily have a data.
LazxState request = LazxState();

// Set the state
request.setState(LxState.Loading);

// Listen the state
request.state.listen((state) {
print(state);
});
copied to clipboard
The Lazx State is made to be used with a Lazx Listener.
Lazx Observer
The Lazx Observer is almost the same as a Lazx Data, the only difference is that there's no state, juste the data to listen.
It could be seen as an abstraction for an Rx Observer to a value.
// Initialize empty observer
LazxObserver<int?> value = LazxObserver();
// Or with an initial value
LazxObserver<String> text = LazxObserver(initialValue: 'Hello');

// Set the data
value.set(1);

// Listen the data
value.observer.listen((data) {
print(data);
});
copied to clipboard
The Lazx Observer is made to be used inside a Lazx Manager.
Lazx Response
A Lazx Response is simply a class to facilitate the response you can get from your sever or data provider.
It will put it in a way that you can easily know if your request worked or not and act in consequences.

// A classic http request, handled with a LxResponse
Future<LxResponse<int>> getTime() async {
try {
final response = await dataSource.httpRequest();
if (response.statusCode == 200) {
// Return a success response
return LxResponse(success: true, data: response.data);
} else {
// Return an error response
return LxResponse(error: response.statusMessage);
}
} catch (e) {
// Return an error response
return LxResponse(error: e.toString());
}
}

// A function that handle the http request result
void showResult() async{
final LxResponse<int> response = await getTime();

//Know if your request succeded
final isSuccess = response.success;

//Get your data
final data = response.data;
print('Result : $data');

//Get the error if there is one
final error = response.error;
print('Error : $error');
}
copied to clipboard
The Lazx Observer is made to be used witht the class that will handle your requests, generally the repository.
Lazx Manager
The Lazx Manager is simply a class made to manage your data globally inside your app.
The manager should be the connection between your repositories and your view models. You handle all your logic
transformation there.
A Lazx Manager is just a little abstraction to handle the Lazx Observer that you could have in them.
class UserManager extends LazxManager {
static UserManager? _instance;
factory UserManager() => _instance ??= UserManager._();

UserManager._();

late LazxObserver<User?> currentUser = LazxObserver();

@override
List<LazxObserver> get props => [currentUser];

//...
}
copied to clipboard
Usually, my managers are singletons as I need them in multiples places in my app, but you can create them as you prefer.
Lazx Widgets & Builders #
Let's see how you can use your data/view model/manager in your different widgets.
Lazx App
A Lazx App is a widget that you will extends on the the root widget of your application.
This one will be used to handle your Lazx Managers if you use them as singletons, to be able to dispose all the used
sink when the app is finished and avoid memory leaks.
class MyApp extends LazxApp {

@override
List<LazxManager> get managers => [MyManager()];

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lazx App',
theme: theme,
home: MyScreen(),
);
}
}
copied to clipboard
Also, Lazx App is an abstraction of a StatefulWidget, so you can override the classic initState and dispose function
Lazx Builder
The easiest one, the LazxBuilder allows you to build a widget each time the value of your LazxData is updated.

⚠️ The state is not used with this builder

LazxBuilder<int>(
data: viewModel.counter,
builder: (context, value) {
return Text('$value');
}
),
copied to clipboard
You should pass a LazxData as the data and the builder will be called each time with the updated value.
Lazx State Builder
The LazxStateBuilder is almost the same that the previous one but it takes the state of your data into consideration.
You will be able to have a "builder" function for each state :
LazxStateBuilder<int>(
data: viewModel.counter,
initial: (context, value) {
return Text('$value');
},
loading: (context, value) {
return CircularProgressIndicator();
},
success: (context, value) {
return Text(
'$value',
style: TextStyle(color: Colors.green),
);
}
),
copied to clipboard
You have a builder function with the name of each state. Only the initial one if mandatory, you can implement the other ones only if needed.
They will be called each time the state of your data is updated.
Lazx State Widget & Data Builder
From the previous builder, instead of having all the builder function for a state inside a builder (that could become long to write in one place if there's a lot of differences) you can have them directly inside a widget :
class LxCounterText extends LazxStateWidget {
@override
Widget initial(BuildContext context, data) {
return Text('$data');
}

@override
Widget loading(BuildContext context, data) {
return CircularProgressIndicator();
}

@override
Widget success(BuildContext context, data) {
return Text(
'$data',
style: TextStyle(color: Colors.green),
);
}
}
copied to clipboard
The same as for the builder, you don't have to override all the function, only the initial one is required.
Then you cand use a LazxDataBuilder wich is simplier :
LazxDataBuilder(
data: viewModel.counter,
lxWidget: LxCounterText(),
),
copied to clipboard
The behavior is the same than with the LazxStateBuilder.
Lazx Multi Builder
The LazxMultiBuilder is like a LazxBuilder but it listen to multiple source of LazxData at the same time.
The widget is then rebuild each time one of the data is updated.

⚠️ The state is not used with this builder

LazxMultiBuilder(
data: [viewModel.counter, viewModel.show],
builder: (context, values) {
return Text('Counter: ${values[0]} & Show: ${values[1]}');
}
),
copied to clipboard
The values list will contain the values of the data in the same order as the list you passed in the data parameter.
Check the examples for more concrete usages 👇
Examples #

Demo App ⚙️ - A simple demo of all the Lazx Widgets/Builders
Lazx Weather ☀️ - A small weather app to showcase the usage of Lazx

Motivation #
So... Why Lazx ?
I'm originally an Android Developer and I learned and practiced Flutter and really enjoyed it. 💙
The thing is that I'm really lazy and when it comes to make a good and strong architecture for your app in Flutter, it becomes a bit complicated and too greedy in ressources.
Depending on what you like (BloC, Redux, Provider...) you will have to create multiple files, handle multiples things, and I felt like I had to make a whole logic and organization, just for the architecture and state management of my app. 🤯
So after having done a few production apps with Flutter, I was really lazy to again, having to setup everything about architecture and state management.
In the other side, I had a really smooth structure for my apps in native Android development and really used to use it. As the other solutions in Flutter didn't really fit my needs and I couldn't find enough resources to use them at their fullest potential I finally decided to do the thing that every lazy person would do : Make my own state management. 🧐
That's how Lazx is born (with this fantastic and long searched name) 🐣
Contributing #
Want to contribute to the project? Here are some points where you can contribute :

Report bugs and scenarios that are difficult to implement
Report parts of the documentation that are unclear
Update the documentation / add examples
Implement new features/tests by making a pull-request
Adding documentation to the readme .
Write articles or make videos teaching how to use Lazx (they will be inserted in the Readme).

Any contribution is welcomed!
Articles and Videos #
Coming soon. 🎬
Dart Version #

Dart 2: >= 2.12

Maintainers #

Borombo

License:

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.