A `repository` is a class that facilitates the interaction between the application and the database. It belongs to the business logic layer since it's responsible for handling data operations. A repository reduces the coupling between the user interface and the data source layer, ensuring that changes made in one layer does not affect the other. By removing direct dependencies between the UI and data source, any changes made to the business layer won't affect how the UI requests data and changes made to the data source layer doesn't affect how the business layer retrieves data.
# The Repository
The constructor of a repository takes a [Dio](https://pub.dev/documentation/dio/latest/) object as a parameter. The headers and URL are set inside of the constructor for the repository so that when dio sends a request, it will know where to go.
The `player_repository.dart` file contains a createPlayer() method that is called from the CreatePlayerBloc to add a new player to the database. Below is the code to the createPlayer method:
description:"Player could not be created. No response from server.");
}
```
The createPlayer() method returns a `Future<BasicResponse>` indicating that it is asynchronous and will return a `BasicResponse` object sometime in the future. The `await` keyword is used when calling the function (from the Bloc) to indicate that the caller should wait for the function to complete and for a future to be returned before executing other code.
In the createPlayer() method, `dio.post` is used to submit data to the server for processing. The string inside dio.post specifies the endpoint that's responsible for handling the request and returning an appropriate response. The data is encoded into JSON format and sent inside the body of the request to be processed on the server-side. If dio returns with a response containing an HttpStatus.OK, the fromJson method in BasicResponse will be called with the decoded JSON data.
However, the dio request also has the possibility of returning a response with a `HttpStatus.BAD_REQUEST` in it. When dio gets a response containing a bad request, it throws a DioError object containing the information about the error response. Inside the catch block, the description is retrieved from the `e` object and stored inside a string called `description`. That variable is then passed into the constructor for BasicResponse and returned.
Inside of the DioError catch block, you'll notice that there is this piece of code:
```dart
jsonDecode(e.response?.data??'{}')
```
The jsonDecode() method is called on the data from the error response. The '??' is a null-aware operator that checks if the left-hand side is null. If the left-hand side is null, the string on the right side is returned. Else, the response data will be returned instead. The '?' in e.response checks if the response is null. If the response is null, it will return null, and the '{}' on the right side of the '??' operator will be returned and passed into jsonDecode().
At the end of the function, if there was an error connecting to the server or an issue with the request object passed to the method, the last return statement outside the try-catch block will be executed.