#100DaysOfCodeChallenge -Crop Management Information System- Day 2
Tags: 100daysofcode, flutter, dart
Published: 2021-06-24 23:22:26

# Recap

On [Day 1](https://dev.to/curtlycritchlow/100daysofcodechallenge-day-1-2lho) I created the FarmerServiceModel that functions as the Dart Equivalent of the Famer cloud firestore document. On [Day 0](https://dev.to/curtlycritchlow/100daysofcodechallenge-crop-management-information-system-22mo) I mentioned I'm using the [gskinner MVC+S](https://blog.gskinner.com/archives/2020/09/flutter-state-management-with-mvcs.html) architecture and shared screenshots of the work I have already completed before starting the challenge.

# Overview

Today I created the `FarmerService()` class and the `AddFarmerCommand()` class. These command is responsible for the S and C respectively for the MCV + S architecture. S for service and C for controller.

Data for this application is stored in cloud firestore. In brief, cloud firestore is a nosql database that stores data in documents. Documents are stored in collections. If you are familiar with sql database you can think of a collection as a sql table (it's more like a list of documents) and documents are like sql table rows (it's more like a glorified Dart Map). You can read more about cloud firestore [here](https://firebase.flutter.dev/docs/firestore/overview). 

# Going Deeper

Let us take a deep dive into today's progress.

## FarmerService Class

The `FarmerService()` class is responsible for making all network request to cloud firestore Farmers collection and Farmer Document. These request include the standard CRUD related (Create, Read, Update, Delete) request. This class is the bridge between the application and cloud firestore Farmers collection.

The main benefit of having all Farmer related network request in the same class is to improve code readability and maintainability. Think about it, regardless of how big my application gets, the future me knows that any Farmer related network request is handled by the `FarmerService()` class.

This class has two key features so far; the Farmer Reference variable and the Add Farmer method. More farmer network methods will be added to this class as the application grows.

### Farmer Reference Variable

```Dart
class FarmerService {
  final farmerRef =
      FirebaseFirestore.instance.collection('farmers').withConverter(
            fromFirestore: (snapshot, _) =>
                FarmerServiceModel.fromJson(snapshot.data()!),
            toFirestore: (farmerModel, _) => farmerModel.toJson(),
          );
  ...
}
```
`farmerRef` is the main variable in the `FarmerService()` class. It stores a Collection Reference to the Farmers collection. The FarmerServiceModel that was created on [Day 1](https://dev.to/curtlycritchlow/100daysofcodechallenge-day-1-2lho) is used thanks to the `withConverter()` method. The combination of the two make the farmer document type safe when the CRUD network request are made. You can read more about this [here](https://firebase.flutter.dev/docs/firestore/usage/#typing-collectionreference-and-documentreference)

### Add Farmer Method

```Dart
class FarmerService {
...

  Future<DocumentReference<FarmerServiceModel>> addFarmer({
    required FarmerServiceModel farmerServiceModel,
  }) async {
    return farmerRef
        .add(farmerServiceModel)
        .then((value) => value)
        .catchError((error) {
      print(error.toString());
    });
  }
}
```  

The `AddFarmer()` method receive a `FarmerServiceModel()` instance from the `AddFarmer().run()` command (more on this later) and call the `farmerRef.add(farmerServiceModel)` method.

This method sends the `farmerServiceModel` data to cloud firestore farmers collection as a Document.



### FarmerService class full code
```Dart
class FarmerService {
  final farmerRef =
      FirebaseFirestore.instance.collection('farmers').withConverter(
            fromFirestore: (snapshot, _) =>
                FarmerServiceModel.fromJson(snapshot.data()!),
            toFirestore: (farmerModel, _) => farmerModel.toJson(),
          );

  Future<DocumentReference<FarmerServiceModel>> addFarmer({
    required FarmerServiceModel farmerServiceModel,
  }) async {
    return farmerRef
        .add(farmerServiceModel)
        .then((value) => value)
        .catchError((error) {
      print(error.toString());
    });
  }
}
``` 
Thanks to the `withConverter` method It only takes 18 lines of code to create a Farmer Document in cloud firestore.

## Add Farmer Command

```Dart
/// This class is responsible for farmer registration.
class AddFarmerCommand extends BaseCommand {
  AddFarmerCommand(BuildContext c) : super(c);

  /// Calls FarmerService.addFarmer method
  ///
  /// Recieves farmer data and buildcontext from widget and pass it to the farmerService.addFarmer method.
  Future<bool> run({
    required FarmerServiceModel farmerServiceModel,
    required BuildContext context,
  }) async {
    bool farmerAddedSuccess = false;

    await farmerService
        .addFarmer(farmerServiceModel: farmerServiceModel)
        .then((value) => farmerAddedSuccess = true);
    return farmerAddedSuccess;
  }
}
```
The only method in this class is `run()`. This method will pass an instance of the `FarmerServiceModel()` to the `FarmerService().addFarmer` method.

# Wrap up

The general idea is that the `AddFarmerScreen()` widget (not created as yet) job is to focus on layout and populating an instance of the `FarmerServiceModel` with user input. In the next post, I will be showing you how these two job will be separated into the LayoutView and the Controller.

The `AddFarmercommand().run()` only job is to pass an instance of the `FarmerServiceModel()` to the `FarmerService.addFarmer()` method. The instance is received from the `AddFarmerScreen()` controller.

The `FarmerService.addFarmer()` method will make the network request to cloud firestore where the `FarmerServiceModel()` instance will be stored as a Farmers collection document.

# Connect with me

Thank you for reading my blog. Feel free to subscribe below to join me on the #100DaysOfCodeChallenge or connect with me on [LinkedIn](https://www.linkedin.com/in/curtlycritchlow/) and [Twitter](https://twitter.com/CritchlowCurtly).