Flutter: Defining a Structure for GetX -Part 2 ( Understanding Models )
In the last article, we learned about how to define a basic structure and a complex structure when starting a new page in flutter using GetX.
In today's post, we will discuss when integrating API calls how to structure Models.
Let’s Dive In
Models-
- So, there are many complex definitions of data model but in its simplest form data model is a way of visualizing data and setting its defined types so you can create functions to process and format it.
- When we add data to a model instance it acts as a temporary memory holder until the app is closed or until the memory cache is cleared.
- Models are required because very frankly when you call an API you can receive multiple fields or data and you can’t just directly use the data response as is bypassing its defined types from the type of data received such as JSON or List.
- Models are going to be required for most of your API calls in general, so how do we structurize them.
- From a directory structure perspective once a model directory is created you can add as many models and once a model is defined we don't need to edit them frequently if done correctly. It's a set it and forget kinda objective.
My structure for a Model directory looks like this -
Directory — models -— — — — — \user_model.dart
— — — — — \login_model.dart
— — — — — \ demo_model.dart
If a structure response has multiple lists or the response is very long it a single page can get too long or a single model class would need multiple model classes to support the base model class in that instance I like to separate those models into a subdirectory.
- Example-
or
Directory — models -
— — — — — \login_model
— — — — — — — — — \login_model.dart
— — — — — — — — — \login_data_model.dart
- In the current example, we segregated our data models which serve for the response of the same API call but for clarity of those two we put them in two files.
- When models are being defined in flutter it's a good practice to declare them null safe using ‘?’ -
Example-
String name becomes String? name
int i becomes int? i
bool isTrue becomes bool? isTrue
- These are useful when any kind of null value is passed to the model it will handle it and avoid throwing an error.
When the type of data is being received is ambiguous or is unknown you can set it to dynamic or var .
- As var and dynamic are by default null safe so need to define them with ‘?’.
Example -
var data1;
dynamic data2;
If you have a JSON model defined you can auto-generate model class for it in a flutter — Some of the favorite sites are.
- To parse string JSON into proper format -
- To create Model Class from JSON -
The app.quicktype.io provides lots of tools to get your model right and just the way you want it. Please do feel free to play around.
Converting Model Class to Observable in GetX -
- So we understood how a normal model is defined and structured but in GetX we can define a Model class as observable.
- There are two ways we can do this —
- You can convert your class values to obs—
- In this model we set every variable type extended with “.obs”.
For Example —
class RxUser {
final name = "Odd".obs;
final age = 2.obs;
}
- So by observable, we mean that whenever the value in the Model changes through GetStreams it will get notified and automatically updated.
2. You can convert the entire class to be an observable -
- In this we instead of declaring every variable we convert the entire class to observable using “obs”.
For Example —
class User {
User({String name, int age});
String? name;
int? age;
}
// when instantianting:
final user = User(name: "Odd", age: 2).obs;
When you are making your own classes observable, there is a different way to update them:
Let's take this Step by Step —
- First, we are going to make the entire class observable instead of each attribute-
class User() {
User({this.name = '', this.age = 0});
String name;
int age;
}
// as we predefining a value to the variable we dont need to make them nullsafe
2. Then in the controller file we need to declare an object and make it observable.
- After that, we will pass the parameters we need to update.
class UserController extends GetxController{
final user = User().obs;user.update( (user) {
user.name = 'Minnie';
user.age = 12;
});
}
An alternate way of doing this would be directly passing the parameter in the Model itself.
// an alternative way of update the user variable:
user(User(name: 'Josh', age: 45));
3. Using it in your View or UI —
class UserPage extends StatelessWidget {
final logic = Get.put(UserController());
@override
Widget build(BuildContext context) {
return Obx(() {
return Text("Name ${user.value.name}: Age: ${user.value.age}");
});
}
}
Summary -
Yay ! we made it so in this post we learned about model class, how to declare variables in the model class, how to structure your model classes for simple and complex projects, and finally how to define observable models using GetX and implementing them in our build View through controllers.
Stay Tuned and thanks for Engaging , Until Next time ✌️