Your Second Flutter App

Nov 30 2021 Dart 2.13, Flutter 2.2.3, Visual Studio Code

Part 1: Parse Network Data

4. Use a Model & Repository

Lesson Complete

Play Next Lesson
Next
Save for later
About this episode
See versions
See forum comments
Cinema mode Mark as Complete Download course materials
Previous episode: 3. Understand Futures Next episode: 5. Make a Network Call

This video was last updated on Nov 30 2021

As you progress in your career in mobile development, you’ll gain an appreciation for the architecture of your app project. Architecture in this context means the structure of your codebase, how different components in your code are connected and depend on one another.

Common architectures in software are the MV* architectures, MVC, MVP, MVVM, and more. The common M in these architectures stands for Model. The model represents the data or content in your app. It describes how you represent or model that data. All apps have data and content, which is why the Model is common amongst all the different architectures.

The MV* architectures are primarily user interface architectures, that is, for software that has a user interface. The user interface corresponds to the V, which stands for View. The View is what lets you see and interact with the app model. For more complicated apps, it’s common to go beyond the MV* architectures, and use architectures that go by the name clean architecture and VIPER.

A common component in all architectures is called a repository. A repository gives the rest of the app access to the app’s data. Other components ask the repository for data when they need it.

Repository classes typically are defined in terms of an interface, which in Dart, takes the form of an abstract class. In the future, when you learn more about app architectures, you’ll learn that an interface is used because it helps with testing your app and also with ensuring your app components are connected in an efficient way. In this episode, you’ll get a start in working with architecture by creating a model class and a repository for the RWCourses app.

The main piece of data for RWCourses is a course. So we’ll make a model class for a course. First, create a new model folder. Once that’s in place, create a file called course.dart in that folder. Add the following:

class Course {
  final String courseId;
  final String name;
  final String description;

  Course(
    this.courseId,
    this.name,
    this.description,
  );
}

As you can see, the course just encapsulates some information about the course itself. Next, create a new folder in lib called repository. Then create a new file in the repository folder called, repository.dart. In the folder, add the following:

abstract class Repository {
  Future<List<Course>> getCourses(int domainFilter);
}

This defines a single method for getting courses. Of course, we’re getting an error because we’re missing the Course import. Add it now.

import '../model/course.dart';

You’ll also notice that we’ve defined a future. We’re going to make a network request which can take a unknown amount of time. This future will return a list of courses for us. We also pass into the domain filter to specify what courses we want.

This is just an abstract class. Now we need a concrete implementation. Create a new CourseRepository file in the repository folder. First, import the repository abstract class.

import 'repostiory.dart';

Next create a Course Repository class.

class CourseRepository implements Repository {
}

We’re getting an error because we aren’t implementing the getCourses method. Don’t worry. We’ll get to that in a moment. First, let’s define an RW API endpoint so we can get the course data.

  String dataURL =
      'https://api.raywenderlich.com/api/contents?filter[content_types][]=collection';

Now to add a method to get our courses, which returns a future list of courses.

  @override
  Future<List<Course>> getCourses(int domainFilter) async {
    final courses = <Course>[];

    return courses;
  }

Make sure to import the courses from the model folder.

import '../model/course.dart';

We’ll need to access our constants, so import that file as well.

import '../constants.dart';

Set the url and then add a filter parameter so that domain specific filters can be applied if in case user wants to.

    var url = dataURL;

    if (domainFilter != Constants.allFilter) {
      url += ';&filter[domain_ids][]=$domainFilter';
    }

In the next episode, with the repository in place, you’ll see how to make a network call in Flutter, and you’ll then use the CourseRepository to make the call.