Cross-Platform Mobile Apps with Flutter

Creating a Data Manager

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Cross-Platform Mobile Apps with Flutter

Check out a free preview of the full Cross-Platform Mobile Apps with Flutter course

The "Creating a Data Manager" Lesson is part of the full, Cross-Platform Mobile Apps with Flutter course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano creates a DataManager class to manage the items in the cart. The class contains methods for adding, removing, and clearing items. Since the data manager needs to be accessed by both the menu page and the orders page, it is declared in the parent class and passed to each page.


Transcript from the "Creating a Data Manager" Lesson

>> The next step is to download real data and see if magic happens. For that, we need to go to the network, okay? And to go to a network, the good news is that Flutter is actually giving us one solution, okay? We do have an HTTP tool to go and grab this, so we don't need to use an external framework.

But it's not included with our project by default. So we need to make a really, really, really tiny process here. So that process is we need to open our pubspec.yaml, that file. And in the pubspec.yaml, there is a section at the top that says dependencies, that one. So we are going to add a dependency.

How to add the dependency here? So right now, the dependency is flutter. Yeah, we know we're using flutter. So at the same level of flutter, we are going to add the name of the dependency. What's the name, http:. What's the colon for? After the colon, you can express one special version, one specific version of that library.

But I want the latest one, so just http: save. And you will see at the bottom right, the IDE will start downloading that package, that's all. This is again like package JSON, like doing MPM install, http package. So now we are ready to write our code for this.

Okay, so now we have the data model, we are actually rendering some dummy items on the screen. We need a place first to contain all the products. So our model needs another place, like a view model, a data manager, another class that will actually be responsible for holding all the products in our menu and also the cart.

So I'm going to create another file that I would call that the datamanager.dart. So the data manager will also be a class, DataManager. And remember that you can move this around, this little flexible pop-up panel from Flutter. I know I need two things. I need a list of category.

The category has the products inside. So we have coffee, tea, frappuccinos, and those are the categories. And we have products inside and that's gonna be the menu. But because that menu can actually, it's going to come from the network, I will need, first, let me import the data model so it's not giving me any error.

And I would probably say for now that at first it might not be there, so I'm adding that question mark. Remember, that means it's optional. And also I will make it private. So _menu. Because I will have a getter later because I will need to fetch the data, okay?

So I will say that, again, if I don't have the data, I will get it later, that's kind of the idea. And then I have a list of items in cart that is like our cart. And they're gonna start this is an empty array. I don't need that to be private.

I can, but I think it's fine, it's not a big deal. And now, I'm going to add a couple of functions that we will use later in the cart for a simple logic function such as adding something to the cart. Of course, I can do this in a separate file.

I can do two data managers, one for the cart and one for the menu. But just to keep things simple here, I have a cartRemove, And then I can have a cartClear that will clear the whole cart and maybe a total. So we can actually get a double as an answer.

Okay, so I mean, the amount of money, the total for the order. So for the add, and we are receiving the product, and it's not just adding that into the array because we have a type issue. The product is the product and this is an item in cart.

If you remember, item in cart has a product and a quantity, okay, so it's not as simple as just adding it to the array. We actually need to do something such as check first if we have it, so I'm going to search in every item. In fact, it's a good moment to actually go over some basic loops here.

So if the product, we can check the ID or just the product, it doesn't matter, is the same as the one that you're asking for to add. It means that the product that I'm adding is already in the cart, so I just need to increase the quantity by 1, okay?

So we are adding products one by one. So I will take the item.quantity++, make sense? And I will say that I have just found it, so there is no need to add it. Because now I will say if it's not found, what I need is to create a new item in cart for that particular product.

So I will say cart.add, we add a new item in cart. Remember we don't use a new key word. And it has the product that is p, and the quantity that is 1. What happens if I add new here? You receive a warning say, hey, unnecessary new keyword.

And I know that your brain says that is not unnecessary, I need a new, but anyway. So we don't need a new, okay? Cool, so that's add, that's pretty simple. Remove, I think it should be even simpler because we can do some kind of functional programming. So we can removeWhere, I received a lambda expression.

I receive an element or an item in the cart and I need to say if I wanna remove that or not. And I will check if the is equal to the ID of the product that you're sending me as an argument. Makes sense? cartClear, will just clear the cart, that's simple.

And cartTotal is just a basic, have a semicolon here missing. This is just plain algorithm programming from programming 101, but we just need to go over all the items on create calculation and total, let's call it total. And we will go through all the items. For each item in the cart, we're going to say that total += item.quantity multiplied by the price of the product, and then in returning total.

And I will still have problems here, types problem. Let's see if you know what's going on. It says a value of type int can't be returned from the method cartTotal. But it's a no, I want to double, why? It's complaining this int, say what?
>> You got int run in doubles.

>> I have integers, but why do I have an integer, right? I'm using implicit type here and I'm starting with a 0. And by default, you think it's double. So sometimes, implicit typing gets you in trouble. So there are two ways to solve the problem. One is instead of var, I can explicitly put the type int, I'm sorry, double, not int, or you can keep the bar.

I'm forced to double by saying 0.0. I have a missing semicolon as well and now I think we are good. We're good to go with the file, okay? But is this downloading data from the network? No, not yet. But before doing that, going back to our main.dart, we try to remember that we have, let's go full screen.

We have pages here, menu, offers, and order. So who needs the data manager for rendering the contents? It seems like the MenuPage because it's going to render the menu, and the OrderPage because it's going to render the cart. So what I need then is to hold that data manager here in the app or in the homepage, okay?

Make sense? So you pick where. You can probably put it at the top level app, or at the homepage, in this case are two widgets, okay? But if you put it at the top, you need to start passing it by. Make sense? It's the same. So someone needs to actually hold the variable.

It's better if it's an StatefulWidget because changing that will probably trigger some changes in the UI. Make sense? So for example, I can add that into the State of HomePageState. There is no need to do it here, okay? As I mentioned before, we can also do it somewhere else.

We can also do it page by page. But if you do it page by page, we have a problem because each page will have its own data manager. So they're not going to share data. And I have the cart in one side, so the menu is adding to the cart.

So I need that data to go to the cart, to the OrdersPage. So what I need then is that both sections, Menu and Order to share the data. So I need to store the data in a widget up in the top level that can access both. Does it make sense?

So for example, we can add the data manager. Here I'm going to create a new one. The data manager is just the class that we have just created that has the list inside. And then I need to pass them by argument to the menu, you pass down into the tree.

How to do that? Well, in the MenuPage, I need a property. A final property, DataManager. Does it makes sense? So I'm going to receive it, it's of type DataManager. And I'm going to receive it as an argument. So I will say required this.dataManager with a lowercase here. Like so and I probably I need to import, sorry, have a type okay I'm writing a different language.

It's dataManager, like so. Okay, now it's working. So on something similar, we need for the orders page even if it's empty at this point, okay? The OrderPage, I need to receive the same property dataManager. I need to import the library, and then I need to received that here required this.dataManager.

The final step is to pass them by argument. I'm just passing objects from one object to another object, okay? Does it make sense? So it's saying that now it's not a constant anymore. Make sense? Because I'm passing an argument. So that OrderPage or those menu page might not be the same every time so I cannot add the const declaration, the const prefix.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now