DEV Community

njoee
njoee

Posted on • Updated on

MVVM With Flutter (Part2){Freeze}

well, before go to this, please take a look at the previous post first MVVM With Flutter (Part1)

Back again!,

continue from previous post, in this post we will focus to Repositories and Model Layer.

Remember We would like to create our codebaseline this way:
The Whole Architecture

so now we are going we have this already from the previous post.
The View And ViewModel

now we are going to focus on this layer, by using API as our datasource.
The ViewModel And Model

in our cases, we have
MainScreen (View)
MainScreenViewModel (ViewModel)
TaskModel (Model)
and we have
ITaskRepository (Repositorires)
as a tools for (ViewModel) to fetch (Model)..
How ViewModel use Repository To Manage Many Model
And Maybe Later On you have XModel can be manage by XRepository and so on...

Lets Take A look into code,

First, you'll create an abstract class like this acting like an interface

abstract class ITaskRepository{
  Future<List<TaskModel>?> getAllTask();
  //and all the method regarding add, update, delet, getById   etc..
}
Enter fullscreen mode Exit fullscreen mode

and now see the implementation code

@singleton 
class TaskRepositoryImpl implements ITaskRepository{
  final String baseUrl = "run.mocky.io";

  @override
  Future<List<TaskModel>?> getAllTask() async{
    var url = Uri.https(baseUrl, "/v3/6bb86bda-08f1-4d7d-99c6-a975bc1201e0");
    final response = await networking.get(url);
    final responseBody = GetTaskDTO.fromJson(jsonDecode(utf8.decode(response.bodyBytes)) as Map<String,dynamic>);
    return responseBody.tasks;
  }
}
Enter fullscreen mode Exit fullscreen mode

from the code above, as you can see. we register the TaskRepositoryImpl into our Dependency Injection and provide it as a Singleton Object whenever we need it.

also, we have method getAlltask() responsible to fetch all the task that user have, meaning return list of TaskModel fetched from the API which we are using http_package

as you can see, we convert all the json response directly into object in this line of code, from this json object

{
  "tasks": [
    {
      "title": "makan",
      "description": "makan di rumah",
      "isDone": false
    },
    {
      "title": "olahraga",
      "description": "jangan lupa olahraga",
      "isDone": false
    },
    {
      "title": "mindfulness",
      "description": "you have to mindfull",
      "isDone": false
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

into GetTaskDTO object like bellow

GetTaskDTO.fromJson(jsonDecode(utf8.decode(response.bodyBytes)
Enter fullscreen mode Exit fullscreen mode

now lets take a look at the GetTaskDTO

@unfreezed //--> this DTO are muttable
class GetTaskDTO with _$GetTaskDTO {
  factory GetTaskDTO({
    required final List<TaskModel> tasks,
  }) = _GetTaskDTO;

  factory GetTaskDTO.fromJson(Map<String, dynamic> json) =>
      _$GetTaskDTOFromJson(json);
}
Enter fullscreen mode Exit fullscreen mode

this GetTaskDTO acting as our (Data Transfer Object) to wrap all the response from the API. and within this DTO there are list of TaskModel and will convert all the tasks object from json response into List of TaskModel..
now lets take a look at the TaskModel

@freezed //--> This object immutable
class TaskModel with _$TaskModel {
  factory TaskModel({
    required final String title,
    required final String description,
    //to set defaultValue using freezed
    @Default(false) bool isDone, 
  }) = _TaskModel;

  factory TaskModel.fromJson(Map<String, dynamic> json) =>
      _$TaskModelFromJson(json);
}
Enter fullscreen mode Exit fullscreen mode

one thing about freezed, YOU HAVE TO MAKE SURE ALL YOUR FIELD NAMING AND CASE ARE FOLLOWING THE JSON RESPONSE FROM THE API

and now you have it. how your viewModel, can access the model through the API.. and convert all the Json Response from API directly into model.

References
http_package
Freezed_package

Next :
How To Use Flutter with Freeze
How To Use Flutter with Injectable

Top comments (0)