Cross-Platform Mobile Apps with Flutter Rendering Data with FutureBuilder
Transcript from the "Rendering Data with FutureBuilder" Lesson
>> So, now that we have this, we are still getting an error here, because menu can be null the first time, right? So if it's null, I cannot return a null because it's asking for a list of categories. So if I know that I do have a menu, because I fetched it, I need to do this, or check if it's null or not, and maybe create an empty one.
[00:00:28] Remember, this is actually saying, open that option and return that option. And actually this code will make the trick of going and rendering something in the menu. It's downloading the JSON, parsing the JSON. How do I know if this is working? Well, first, who is going to use this?
[00:00:49] Menupage, okay? So in menupage, I was doing this dummy product thing that I don't think I want. What do I want here? I wanna go and talk to the data manager. So I have a list view here. What if instead of this, I'm rendering a text, just to see if something works.
[00:01:10] And in the text, I will say items or categories, Available. And I will pull here an expression saying dataManager.getMenu. So this is going to get the menu, right? That was kind of the idea. So I'm getting the menu directly like this. And from this, I can take from the menu.
[00:02:17] I mean, I can, so then I can render the value, but it's kind of weird that I'm doing this within a text. So to solve the problems and work with futures, there is a much better way. So Flutter has something known as FutureBuilder. What's a FutureBuilder? The FutureBuilder is actually a widget that will be based in a future.
[00:02:49] Again, what's a future? A value that is coming later, okay? That's kind of the idea. So the FutureBuilder works in this way. You will understand the whole idea in a minute and I think that you will like it, because it's actually pretty good. The FutureBuilder receives first a builder.
[00:03:10] What's a builder? There are some elements, some widgets in Flutter, that instead of receiving children, they have a builder. A builder typically receives a context and an index, okay, typically, but it depends on the case. Some builders will get you something different, okay? So it depends on the builder.
[00:03:30] In this case, you're getting something known as a snapshot. In fact, I think that you get the signature there, as an example, okay? You'll understand what's going on in a second. I think I have some parentheses issues. So let's balance this. This goes to a newline, okay, that's fine.
[00:03:52] So here, what I need to do, I need to return something, for example, a text, okay? Saying something, a widget, so a builder returns a widget, okay? What's going on? What's a snapshot? A snapshot is a variable that will contain the data from the future, but it also will contain properties such as this, hasData.
[00:04:18] So if it has data, we can do something, if it doesn't have data, we can do something else. So while it is waiting for the future to finish, It will actually go to the else, and here in the else, we can render anything such as for example. And by the way, if it doesn't have data, maybe it's because there is an error.
[00:04:41] So an exception has happened. So the future actually reject the data. So, what we can do here, we need to return different options, such as there was an error loading the data. This is a const, and here there is a CircularPogressIndicator that we can use as well, so we can return that one.
[00:05:09] What is that? An animation with a circle. So this means the data is in progress, so the future didn't finish. Make sense? If we are here, it's because the data is not there because of an error. So we are rendering an error. And if we have data, the future has finished, data is ready.
[00:05:40] So with a FutureBuilder, we have this way to actually render different things on the screen for different situations. Does it make sense for now? So we can release a widget, so we can use it anytime that we have widget that needs to go to the network or to other places that are future-based, And then render content on the screen.
[00:06:08] But where is the data coming from, because we need to specify where the future is? And the future is the dataManager.getMenu. Okay, so we are asking the FutureBuilder to build a UI based on the future. The future has different states. What's a future? A promise, a promise of a future data, okay?
[00:06:32] That make sense, kind of? So if we do have something, maybe we can return the text for now, taking where is the data? Actually the snapshot has the data. Okay, the snapshot has the data. So what do I need to do with that data? I can install that into a variable, sorry.
[00:06:56] So my data is an array of categories, so you can call these categories, and I will say is, I know that the data is there, why? Because I have already asked for it. Because if there is errors, the data is null. Does it make sense or did you get really complicated?
[00:07:18] So now, I can say there are categories_length. Can we get length? Well, the promise said it doesn't know what it is. So what you can do here is I can say, as something, I know it's a list of category. Does it make sense? So now, it has a length.
[00:07:47] So let's summarize what I've done here. So this is my menu page. My menu page right now is rendering a FutureBuilder. So it means that it's rendering some content based on requesting that content from a future. Does it makes sense? The content, for a while, it's loading, and for that, we have here a CircularProgressIndicator.
[00:08:15] Maybe there is an error at some point in the future process. For example, there was an error with parsing the JSON or wherever you define as an error, and then it's going to render this. And if we have data, it should render a text. Does it make sense kind of?
[00:08:34] So let's rerun this in Chrome.
>> So a FutureBuilder just keeps getting rebuilt?
>> We are in a state with widgets, so actually once it was rendered, there will be no rerendering. Does it makes sense? And, I mean, it still doesn't look super great, but I think you should get excited about that little message saying, there are four categories, because that's actually the data coming from the server.
[00:09:14] I didn't hack all that, okay? I mean, we didn't see that circular indicator because it's actually going really fast, okay? So that's why we didn't. We can try to reload here and see if it's right to turn on this again and keep this up to the right, so we can actually preview what's going on.
[00:09:38] Let me rearrange a little bit this, like so. Oops, Like that. So if I refresh, now the JSON is coming really really fast, so that's why we're not seeing the measure. But let's see, if there is an error, we can actually see that because I can just force an error in the URL and see if that happens.
[00:10:05] So now, I don't wanna see a text saying there are four categories, I wanna see the categories, right? So to do that, I need a column or a list view, because we want to scroll, remember. So I want a ListView, but in this case, the ListView, remember, has children, and I need to pass the array.
[00:10:30] Can I pass the array of categories as an argument? What do you think, like here? No, because this is a list of category, not the list of widgets. Does it makes sense? So yeah, I can map these into, but it doesn't work like this. So ListView has another way to create a ListView with a builder.
[00:10:59] Okay, so this is actually a factory constructor or a name constructor. What's an item builder? I will receive here context and index, and I need to return a view. So actually, this is how it works. The index is actually the category that I need to render. So I need to return here, what do I wanna render for that index?
[00:11:22] So for example, I can render, you will understand finally what's going on in minute. So I can render categories[index].name, so a text with that. I need to put semicolon here, and I think I have a parenthesis balance issue. Yeah, I need one more to close the builder. There we go.
[00:11:48] So now, what we have here, where I'm going more for some reason, we'll check in a minute. But I see hot coffee, ice coffee, tea and snacks. So this is actually going through the ListView, okay? Any questions on this one? So why do we have an error? Because actually, if you look at the ListView builder, the ListView builder doesn't know about my categories array.
[00:12:22] So it doesn't know how many items it should render, okay? Does it make sense? So it doesn't know. I can actually say so with itemCount. So I will say, hey, you know what, you will have four only. So don't ask me for more because I don't have more.
[00:12:41] It's not an infinite list. So actually, with this, you can make an infinite list, you don't pass account. And actually what will happen is that if you have 1000 elements, it's not going to ask you for the 1000 at the time. When you start scrolling, it will start asking you to the builder function, hey, I need the fourth one, I need the eighth one.
[00:13:06] Give me the widget that you want for this particular item. So this is actually looping through the categories. Of course, I can now add more widgets, such as icon with a padding on everything that you know here. So now, we have padding on them.