[BEEP] [MUSIC PLAYING] EMILY FORTUNA: Hello, and welcome back to “The Boring Show.” I’m Emily Fortuna EMILY SHAK: And I’m Emily Shak EMILY FORTUNA: Welcome So yes, you may have seen Emily on stage with me at Google I/O a couple of times now EMILY SHAK: I think it’s been three [LAUGHTER] EMILY FORTUNA: And I’m super glad that you could join us on “The Boring Show” as well EMILY SHAK: Yeah Thank you for having me I’m excited to be here EMILY FORTUNA: So when we last stopped, Andrew and I were working on adding a database so that we could favorite articles And we sort of had that working We were running into some issue where the UI wasn’t always getting updated with the stories that we were adding, but it seemed like our database was So the mystery continues We get to dig into what’s going on First of all, I was thinking about this a little bit And I think there may be an issue with the stream that we wrote So if we go over to our Favorites file, we have this we have our class with– where we can query the database And if in our “is favorite,” we are investigating, in our table, trying to select a favorite– an entry in our favorites table, and watch it And I’m wondering if there is an issue with– if our favorite doesn’t exist in that table, maybe it’s trying to query it, seeing there’s nothing, watching on that forever, and then we’re filtering And if there’s like– if we’re watching on nothing, maybe it doesn’t fire EMILY SHAK: So does this work if you were to rewrite it such that we’re just watching the full table, and then updating based on that, rather than just watching a single row in that table? EMILY FORTUNA: We should try EMILY SHAK: Let’s see EMILY FORTUNA: So yeah, let’s test that out So let’s see, we want to select the whole table Launch And then, from that, we want to just filter where our favorite is the ID that we want So watch.where I think we should just be able to do that And then we convert that list to test if there is at least one It should be only one, but– oh, map it Favorite.ID What is it not happy about? EMILY SHAK: So I think favorite here would be the full table, rather than the individual– EMILY FORTUNA: Oh, right EMILY SHAK: –item EMILY FORTUNA: OK, so let’s call this favorites list Favorites list All right So we want to actually say, in that list– yeah, OK So how about a– sorry, you were saying? EMILY SHAK: Do you think we should map here, and then– EMILY FORTUNA: Yes EMILY SHAK: –map that list to any entries that might match our query? EMILY FORTUNA: Favoriteslist dot– don’t we want to actually, from that list, inspect it, right? Inspect within the list EMILY SHAK: Mhm EMILY FORTUNA: So yeah, OK Map works Map And then, inside that list, we want to say where favorite.ID equals ID? And then– EMILY SHAK: Are you missing a paren at the end? EMILY FORTUNA: Yes EMILY SHAK: I get to be the one who sits here and just scrutinizes all of the code EMILY FORTUNA: Works out EMILY SHAK: Yeah EMILY FORTUNA: OK, so we have– so we’ll get rid of– well, let’s just comment this up for– And I think– yeah, filter from that and just–

is there any– are there any that have that? EMILY SHAK: Yeah If feel like we could simplify EMILY FORTUNA: Yeah, that’s kind of wacky EMILY SHAK: We got two maps EMILY FORTUNA: OK But– EMILY SHAK: I mean, it should work, right? EMILY FORTUNA: Yeah EMILY SHAK: We can at least use this to test if it works EMILY FORTUNA: Sure What if– let’s see, what would be the better way to do this? It would be to– there’s a filter? OK EMILY SHAK: Can we just check, at the end of the where call, if the length is greater than 1? Do we need that last map? EMILY FORTUNA: Let’s see Where– that should return a list– yes, correct So that dot length And then yeah, get rid of this Oops [SCOFFS] EMILY SHAK: Happens more often than I’d like to admit [LAUGHTER] The selecting and moving to a different part EMILY FORTUNA: OK, so yes That looks a little better So we’re taking– we’re watching the entire table, getting the list of all the entries in that table, filtering to find the ID, and then, from that resulting list, it should be only one We have greater than 1 Whatever Greater than or equal to 1 Yeah, OK So let’s test this to– I’m going to do a hot restart just because this is a standalone– this is not Flutter It’s like your dart So it wouldn’t run the build method OK So now the moment of truth here All right, all right EMILY SHAK: It seems reasonable EMILY FORTUNA: Yes EMILY SHAK: Does that get around the issue you were seeing before? EMILY FORTUNA: Yes So let’s stick this stream builder back in the expansion title, where we had originally intended it to be, rather than this weirdo thing above And just for grins– oh, my gosh OK, and I guess– so the moment– the real way to test this is we need to– let’s stop it and pull it up again Because it should persist across runs That’s the whole point of this database business So we will pull it up again So I think the question, for me, is I thought with Moor, I should be able to– we should to look and see if that’s expected behavior Because I thought that it should behave this way And if not, then we should file a bug EMILY SHAK: Yeah, let me go ahead and look at the Moor plugin EMILY FORTUNA: OK, yeah, while it’s building EMILY SHAK: Is it this one? EMILY FORTUNA: Yes EMILY SHAK: All right Let’s just take a look here EMILY FORTUNA: And the good news is it does– we are seeing those persists So we’d just written query wrong Or actually, I think that query should work We’ll look at the docs EMILY SHAK: Yeah So I think– so this seems to correspond to what we’re doing now, which is looking at the whole table, I think EMILY FORTUNA: There was another page that has full docu– oh, scroll up for a second Check out the documentation for a more detailed guide EMILY SHAK: Sure EMILY FORTUNA: Writing queries EMILY SHAK: All right EMILY FORTUNA: Let’s see Select blah ware watch EMILY SHAK: So this one looks like we’re watching an individual row, like you were doing before EMILY FORTUNA: Yeah EMILY SHAK: So that’s supposed to work EMILY FORTUNA: Yeah, so I think the one other way I can test this is– or check this is they have– I downloaded the repo, and I can look in their tests Yeah, so if I look in streams test, I just want to see how they wrote their tests to see if it’s like– EMILY SHAK: Yeah If there’s a test for that particular– EMILY FORTUNA: Right, yeah EMILY SHAK: –watching one line in the table EMILY FORTUNA: Or anything to indicate, this is not supported or whatever OK, so fetch when the first listener attaches Or just selecting looks like on [INAUDIBLE] So that’s like the table This is the table, table Or wait, look first

Yeah Their tests are not amazing They only test on the table So OK, let us– we’ll file a bug And either they can tell us, no, you’re using it wrong EMILY SHAK: Yeah, it could be that they don’t intend to support this, and just might want to be a little more clear about this documentation EMILY FORTUNA: Yeah Yeah, when I read it– because it literally says it will– it will automatically– whenever the underlying data changes Which to me says, like, anything in the table, but maybe I was wrong So let’s file a bug Do you want to do it on your computer? EMILY SHAK: Sure All right EMILY FORTUNA: So scroll up There’s the repository link on the About section Above EMILY SHAK: Oh, here? EMILY FORTUNA: Yeah Click on that EMILY SHAK: All right EMILY FORTUNA: And Issues EMILY SHAK: Yeah I wonder if they already have one, or if we need to add a new one EMILY FORTUNA: Improve code ish Unless– yeah, let’s look at that one Only tests– EMILY SHAK: No EMILY FORTUNA: Exactly what we were commenting on Your coverage could be better EMILY SHAK: No, they’re just talking about in general Like, how do we know what our coverage is, I think EMILY FORTUNA: Oh EMILY SHAK: Rather than– EMILY FORTUNA: Oh Oh, interesting EMILY SHAK: Oh, but this does kind of indicate there are tests elsewhere EMILY FORTUNA: Mm OK EMILY SHAK: Is there any other directory with– EMILY FORTUNA: Let’s see Tests Oh, see, now, what I am doing? Select test There’s two– EMILY SHAK: This feature is actually something that would be super useful for me in my day job [LAUGHTER] I would love if we could do this also EMILY FORTUNA: Oh, nice Let’s see OK, yeah, there’s more Flutter, more generator, and Moor Let’s see if they’re testing those Moor Flutter Oops I can totally type There’s no tests in Moor Flutter EMILY SHAK: Meanwhile, I’m going to start filing an issue, just in case we do need it EMILY FORTUNA: Thanks Oh, there is a Moor title I’ll look in there Multitasking for the win They’re not testing that thing in their other tests So I think we should– we can safely do it EMILY SHAK: All right So what should I say here? I said, “watching a subset of a table doesn’t reliably update with results.” Is that– EMILY FORTUNA: I wonder– EMILY SHAK: –accurate? EMILY FORTUNA: Yes, but I wonder if the issue is– I could be wrong, but my supposition on what’s happening is like, if we watch for a line that’s not– a row in the database that’s not there, that’s my guess of what the problem is Let me– EMILY SHAK: And then when it updates, it doesn’t update the query, it just– EMILY FORTUNA: Right Because there’s nothing there EMILY SHAK: It ran the selection once to find, this is the section that we’re looking at, and then didn’t see any section, so it’s not updating? EMILY FORTUNA: Right That’s my guess Let me test that a little bit more Ha-ha-ha Moor And then we can– but I would say keep typing that EMILY SHAK: Yeah EMILY FORTUNA: Do you want me to send you this query? Or you have the query because it’s– EMILY SHAK: Do I have the new one? EMILY FORTUNA: –in the repo No, but you have the old one– EMILY SHAK: Oh, the old one EMILY FORTUNA: –which is the one that we need EMILY SHAK: Yeah EMILY FORTUNA: And I mean, yeah, you probably don’t need to copy that query literally, but use it to say what we’re doing OK, so while you do that, I am going to test my theory that this thing is only run So hot restart EMILY SHAK: Got some markdown code blocking in here EMILY FORTUNA: Excellent EMILY SHAK: Yeah, fancy EMILY FORTUNA: People love it when their bug reports are readable [LAUGHTER] EMILY SHAK: And when the people filing them have gone through the necessary steps to determine that it is a bug EMILY FORTUNA: Oh, true Yeah This is also, I would like to say, I hope best practices for bug filing Sometimes, in my history of working with open source, I’ve gotten things where it’s like, blah doesn’t work And you’re like, OK, but– EMILY SHAK: Yeah, we’re going to try and give as much context for what we were doing and what we expected EMILY FORTUNA: Yeah, yeah So if you can say how you got into that situation, what happened, what you think should happen– and so sometimes, bug reports can take a little bit

But the more information you get, the better But also, I will say I know– I’ve talked to Eric Sidel about reporting bugs in the Flutter repo And sometimes, I’ve encountered things where I’m like, this isn’t reproducible So I don’t know how to file a bug And he’s like, file it anyway because if we have a record of something happening, then if something similar happens, maybe we can put those two together and be like, this is a trend, as opposed to like– so if you see something weird, err on the side of filing it But the more information you provide, obviously, the better EMILY SHAK: And of course, be polite EMILY FORTUNA: Yes, absolutely Because we are providing free software for you [LAUGHTER] Anyway– EMILY SHAK: We love when you send bugs EMILY FORTUNA: Yes [LAUGHTER] OK, so my theory I will print out whether this is really rerunning to check that So yeah, just to be clear about what I’m doing here to test this If it’s the case that the query isn’t behaving the way you expect it to, it won’t refire So I’m just putting a print statement to check if it’s– if it refires, the builder will run Yes I should– I think that should work So I hit this Of course, now it works as I expect EMILY SHAK: Oh, does it? EMILY FORTUNA: Well, I’m going to do– EMILY SHAK: Are we finding out this isn’t a bug at all? EMILY FORTUNA: I’m going to do a full restart just because I don’t really I’m not sure how hot restart works outside the context of Flutter code I thought it just reran everything But if it’s working, I’m like, I don’t know So I’m just rerunning from the– EMILY SHAK: Yeah EMILY FORTUNA: –from the get-go just to be extra– EMILY SHAK: I would expect hot restart would work Hot reload, I wouldn’t necessarily, depending on the context EMILY FORTUNA: But now it works That’s why I was like, why didn’t it work before? EMILY SHAK: All right So are we supposed to be seeing– EMILY FORTUNA: OK, there So I pressed this It didn’t do anything It’s causing inception because it can’t– it’s a unique key It got added to– you can see it– let’s see Minnesota Oh, my gosh I need to clear our little favorite things It’s hard to read Favorites Yeah, so we tried to add it It’s already in there But our UI didn’t update and we didn’t see that rebuilding thing, which suggests the query isn’t functioning as we expect it to So yeah We’ll write it They can say that’s not an intended use case, or I’ll fix that In either case, this is a cool plugin We just want– EMILY SHAK: Oh, yeah, for sure EMILY FORTUNA: –it to work correctly, or as awesomely as possible EMILY SHAK: Thank you for contributing plugins to our open source ecosystem EMILY FORTUNA: You bet You bet EMILY SHAK: We really appreciate it “However, as far as I can tell, the database is updating, but it’s not causing”– I want to write– I want to make sure that it’s clear that it’s not that we’ve written the UI part wrong without providing too much context EMILY FORTUNA: Right So I think you should say, we suspect it’s because this– there’s no favorite with that ID to start with And oh, here’s another way to check that, actually So do I have– let me kill this again and restart But I think another way to test this is now that I have some favorites in there that are– and I’ll see if I can remove them And if that’s the case– so I tested the adding one, and it was like the UI didn’t update But if I can remove it successfully, then that again suggests that– EMILY SHAK: OK EMILY FORTUNA: That it’s that starting query, or starting

WHERE clause, the watcher that’s not behaving as we expect Of course– OK, so we got this one OK, so it successfully updated– yeah Yeah, if it starts there– EMILY SHAK: OK, so I’m going to write this a little differently “However, for my use case, the entry in watching might not exist before you make the first update The behavior I’m seeing is that when I make that first update and add it to the channel, my UI does not rebuild Then, on all subsequent updates”– well, do I have to restart the app before the subsequent updates will work? Does it have to have started with– EMILY FORTUNA: No, but it needs to rebuild in some way So a way to rebuild is if I scroll down and scroll up, it scrolls in– or if I go to new stories and come back– that’s interesting EMILY SHAK: Cool, cool [LAUGHTER] EMILY FORTUNA: Hold out for the next bug report [LAUGHTER] So there’s– our theory isn’t quite perfect But maybe we can describe what we’re seeing and hopefully– so wait Let me check my print out I’m printing out the entire table, so we should be able to see what’s actually there Is that– oh, did I delete? I think it’s still could be what’s going on Because– or wait, no OK, we’re going to describe it as it is There’s something else going on It seems to sporadically fire when you watch on a single row, and I’m not quite sure– but this is a clear case There’s a little more to it EMILY SHAK: Mhm EMILY FORTUNA: Let’s see EMILY SHAK: Something like that? EMILY FORTUNA: Yeah, looks good, looks good And I actually– before I started using this plugin, I was checking the response on issues and stuff And the plugin maintainer seems to be quite quick and stuff EMILY SHAK: Oh, good So we may get an update for the next episode EMILY FORTUNA: Yes Yes, stay tuned All right, for now though, we will go back to watching on the entire table, which is a little disappointing because it’s a little less efficient than what I might have hoped But it is what it is EMILY SHAK: Can you not just do command backslash? EMILY FORTUNA: I did not know that one EMILY SHAK: You– EMILY FORTUNA: Select these? EMILY SHAK: Select those three rows EMILY FORTUNA: OK, then there EMILY SHAK: This one EMILY FORTUNA: Oh EMILY SHAK: Backslash Yeah Right Write it up EMILY FORTUNA: Oh, nice Thank you, Emily EMILY SHAK: I got you EMILY FORTUNA: This is why pair programming is awesome EMILY SHAK: We have found so many keyboard shortcuts that the other one didn’t know about in prepping for our I/O talks EMILY FORTUNA: True story EMILY SHAK: It’s been really helpful EMILY FORTUNA: True story All right, so OK, I can take out my rebuilding, debugging I think I might have had another print statement in here from– print everything Yeah, we can get rid of that EMILY SHAK: That’s a fun method [LAUGHTER] EMILY FORTUNA: Print the world OK All right, now we should have less things spewing in our– OK, so back to what we were originally intending on doing We can favorite things, but the whole idea was we want to have a Favorites page that we can go back to look at so we can read these favorites later

The question is, UI design Where should we put it? EMILY SHAK: Yeah, so I could imagine that it could be a third tab in that bottom tab bar It could also be some other page that gets pushed over the others, and you trigger that from some other menu But I’m not a designer EMILY FORTUNA: Me neither EMILY SHAK: Designers, super important for your team EMILY FORTUNA: Yeah, so I could see it being– you’d have a third tab at the bottom here We could have the hamburger menu thing, where you have the three lines as a dropdown And you could have your– it’s a little different because these are externally provided, whereas like Your Favorites is a personal thing You could also have a Preference menu The good thing is– EMILY SHAK: Yeah, I mean, if we think we want to add a Preferences menu at some point, maybe we have a bunch of settings or things we could be looking at in some menu, and this could be the first of many EMILY FORTUNA: Yeah, I suppose you could also theoretically have things– we could check if Moor does this, but you could have a maximum database size for how many articles you’re allowed to save, so that your app– if you’re an “article hoarder,” you’re just saving everything, this app could slowly take over all the storage space on your phone So that could be a preference EMILY SHAK: I mean, kind of your fault at that point [LAUGHTER] You know what you did [LAUGHTER] But sure, sure EMILY FORTUNA: I’m just starting to think of settings We could also have offline syncing or something, or weather settings could be set EMILY SHAK: I want to see a dark mode EMILY FORTUNA: Ooh, OK Just because of that, we’re having a Settings page OK, so we will add– let’s do a little hamburger button thing in the top corner EMILY SHAK: OK EMILY FORTUNA: Maybe scooch our little loading indicator over, and then– EMILY SHAK: Yeah, what is the why right now? EMILY FORTUNA: So basically, it’s indicating– EMILY SHAK: Ah EMILY FORTUNA: Although we also have this EMILY SHAK: Oh, that’s kind of fun EMILY FORTUNA: Yeah Oh, that’s fun I think Philip was saying that this occasionally happens, that we need to deal with it But keep going and try again EMILY SHAK: It’s just kind of flaky? It doesn’t always happen? EMILY FORTUNA: Yeah Well, so that was a deserialization error So we were getting information So this pings the Hacker News API and– EMILY SHAK: I mean, with this message, it looks like it was getting null and it tried to serialize it as an article EMILY FORTUNA: Right So we were getting– EMILY SHAK: So where are we serializing those? Can we check for null? EMILY FORTUNA: Where we’re deserializing? EMILY SHAK: Yeah EMILY FORTUNA: Yeah, so I imagine– yeah, we should just be able to add that Deserialize Is this our code? Not value, not let’s build IU Get article Here we go EMILY SHAK: So in that function, could we check to see if the string is null? And if so, just return null, and then expect that from the caller? EMILY FORTUNA: Yeah, iterator I just want to check to make sure– where is the iterator? Because I want to make sure that it’s– I want to ensure what– or know what is null If it’s the whole string or if it’s a part of the string– a portion in the string, you know? Where is iterator? Try calling iterator Oh, object is iterable OK EMILY SHAK: I want to say that just means that it’s trying to iterate on an object, and the object is null But we’re not going to see an explicit call to something called iterator EMILY FORTUNA: Right Well, we’re calling it iterator Iterable EMILY SHAK: Yeah EMILY FORTUNA: Yeah So this is the iterator But I guess what I’m asking is, is the whole string null, or is that piece null? And so that’s why I wanted– well, OK, let us– we can check Parse article Let’s just have a– if JSON string is null, we skipped that article because it’s garbage Where does this get called? Find Moor references So caching articles on our test Really? It’s only in– oh, it’s cached [INAUDIBLE] EMILY SHAK: So just check if storyres.body is null here?

And then don’t do anything if it is? EMILY FORTUNA: Yeah Well, I just want to see where this is called this article ID Do we handle this? No, we don’t Thanks, guys We can say where– we can return null, and then filter where not null EMILY SHAK: Yeah EMILY FORTUNA: That’s kind of a crappy way to do it, but it’s what we’re going to do right now Where article [INAUDIBLE] EMILY SHAK: And then I think we still need to go into the call to get article EMILY FORTUNA: Yes OK, so if storyresult.body is null, then you should– do we want to throw this error? EMILY SHAK: Yeah, I mean, now that we’re OK with it being null– EMILY FORTUNA: Yeah EMILY SHAK: Not knowing the history of that error at all EMILY FORTUNA: Me neither So long OK, so storyres.body is not null And so otherwise, we’re just going to– do we want to set it to null? EMILY SHAK: I don’t think we need to, right? EMILY FORTUNA: Yeah, you’re right Because it will, by default, return null if there’s nothing there OK, I’ll do a hot restart just for grins on that And hopefully, we never see that again Let’s see Great We fixed it, for sure OK, onto what we were going to do EMILY SHAK: Yeah EMILY FORTUNA: Hamburger method So I forget what that’s called, the hamburger menu Do you remember? It’s like the tail dropdown menu Side menu Flutter material– EMILY SHAK: Looks like it’s a drawer EMILY FORTUNA: So that’s the actual thing But can you specify the icons? EMILY SHAK: Oh Yeah EMILY FORTUNA: I’m just asking about the icon EMILY SHAK: You’re just looking for the icon OK EMILY FORTUNA: I mean, oh, but yeah, we should– we can use a drawer Let’s use a drawer EMILY SHAK: Cool EMILY FORTUNA: Do the whole thing OK, so they have– oh, they just specify like that and it does everything Amazing OK so– EMILY SHAK: Yeah, and the drawer can have children EMILY FORTUNA: OK, great EMILY SHAK: Or one child EMILY FORTUNA: OK, so drawer I have never used a drawer Drawer And then list view EMILY SHAK: Where? EMILY FORTUNA: Oh, I see EMILY SHAK: I mean, at this point, it’s up to us EMILY FORTUNA: Yeah Well– EMILY SHAK: We can just have– EMILY FORTUNA: We’ll just have our one So we’ll have Favorites page Let’s just have text to start with Favorites page, and we’ll do something– we’ll make that a real thing in a minute OK Why did that not appear? Do you think it’s because we have our Y Combinator thing? Let’s look where that is EMILY SHAK: Yeah, where’s that being built? EMILY FORTUNA: Home Let us use the widget inspector No I haven’t used Dev Tools and VS code in a while EMILY SHAK: And it shows EMILY FORTUNA: Yeah, right? Downloading updates There we go OK, so we want to– where’s my little– oh, select widget mode Go to simulator Add bar, loading info

EMILY SHAK: I think you’ve transposed the F and the O in your search query EMILY FORTUNA: Oh, thank you Oh, I found it OK, so loading info Where’s that put in the app R? Oh, OK Scaffold leading Can we not have a leading and a drawer at the same time, so that maybe– I’m going to make it go away for a second and see what happens Oh, yeah Apparently not EMILY SHAK: Hm EMILY FORTUNA: That’s sad But we have to have it Maybe I can stick it next to the title or something, or off to the side of the title Is that terrible design? We will be sad if we have two things EMILY SHAK: I’m just wondering like– EMILY FORTUNA: Too much stuff? EMILY SHAK: Well, it would be super cool I bet we can’t do it right now, but it’d be super cool if the hamburger menu icon was the same as the Y Combinator menu And so when you went to the loading thing, it flipped over and showed the Y, and then flipped back to the hamburger menu and became– EMILY FORTUNA: Mm We could do that with an animated switcher EMILY SHAK: Ooh, I’ve never used one of those EMILY FORTUNA: Basically, it toggles between two different things– two widgets Let’s try it EMILY SHAK: OK EMILY FORTUNA: We’ll see what happens Meanwhile, people at home are like, I just want a Favorites page EMILY SHAK: The loading info is already doing some animation itself, though, right? EMILY FORTUNA: Yes EMILY SHAK: So we would need to strip that out or not use that? EMILY FORTUNA: Well, I think it would be cool if we could still swap habit spin and then swap back EMILY SHAK: OK OK, cool EMILY FORTUNA: Do you think? What do you think? EMILY SHAK: No, I’m just– I don’t know what it’s going to look like, but I’m excited to find out EMILY FORTUNA: Well, I don’t quite know either We’re going to– yes, we’re going to discover this OK, so let us– I’ll just copy that Drawer So right now, that’s a thing It’s not what I expected EMILY SHAK: What? Oh, yeah, probably we need some container that makes it white or something EMILY FORTUNA: I guess EMILY SHAK: I don’t know EMILY FORTUNA: Why are you not doing this? There we go Wrap as container [INAUDIBLE] And let’s just make it a height of 300 because that’s arbitrary No, I’m still in– erg I’m in the select widget mode thing Dev Tools, cancel widget mode Phew OK Yes So now– oh, the Favorites page is way up there OK, that’s not important right now EMILY SHAK: Exactly what we wanted to have happen EMILY FORTUNA: Yes [LAUGHTER] That’s entirely what I intended I just need to wrap in a [INAUDIBLE] It’s kind of interesting that the drawer has its own– it’s not using [INAUDIBLE] Anyway– EMILY SHAK: I mean, it makes sense that you would want full control over everything in there EMILY FORTUNA: Fair enough, fair enough EMILY SHAK: With great power comes great responsibility EMILY FORTUNA: And great design requirements OK, so back to this icon, let’s see Can you specify an icon in drawer? Custom? Oh, OK, no, but we don’t need to do that All we need to do is– so this we are listening for whether something is loading or not with the Y Combinator, little animator thing And so what we can do instead is we can still listen, and if it isn’t loading, have it display the drawer thing And if it is– EMILY SHAK: Is that going to animate between them? EMILY FORTUNA: We can wrap that in an animated switcher EMILY SHAK: OK EMILY FORTUNA: But all of it comes from whether we are loading or not EMILY SHAK: Mhm EMILY FORTUNA: So I’m going to copy this and go here

And close my parentheses Another parentheses OK, and when we figure out what we’re doing, let’s make this not a one-liner What have I done? Mm, trying container EMILY SHAK: I wish there was a plugin that could just say, you have a bunch of parens and brackets that look messed up Let me just go ahead and match them up for you EMILY FORTUNA: Fix them? Yeah EMILY SHAK: That’s probably the kind of thing that’s like impossible to do, though EMILY FORTUNA: We should work on that, for sure OK, so container [INAUDIBLE] OK Text, container, drawer, semicolon, bracket Do we just delete that? Is that the– EMILY SHAK: Cool EMILY FORTUNA: OK, phew OK, so we are listening for whether it’s loading or not And I think loading info is doing all this checking states right now What are we doing with– [INAUDIBLE] value notifier is loading Where does this get called? Oh, so we add a listener, and this returns nothing It would be nice if this were a stream I think I had this as a stream and it got changed So loading tabs counts is an int of the tabs that are loading I guess– oh, wait OK, so consumer of the provider package, it gets called whenever this value changes So I think all we need to do is check the value and do something If it’s 0 versus greater than 0 EMILY SHAK: Cool Sounds good EMILY FORTUNA: So let us do– we’ll wrap this in animated switcher Animated switcher And we will say, [INAUDIBLE] is loading This is kind of repetitive Loading is greater than 0 Oh Loading tabs count What is that? Dot value Great OK, and then animated switcher, you take– your child is dependent on– so is loading If it is, we want that loading info, I think it’s called? Yeah, loading info– loading EMILY SHAK: Oh, an animated switcher just takes one child rather than the two things that it’s switching between? EMILY FORTUNA: Yeah, it’s a little funky that way And then I think we need– what is it complaining about? Duration We need a duration Duration, duration Let’s make it– EMILY SHAK: 150 milliseconds 500 milliseconds Some number [LAUGHTER] Perfect EMILY FORTUNA: OK, so half a second So in theory– now, these may have already loaded, so it may not do anything EMILY SHAK: Although that one looked like it was– EMILY FORTUNA: It looks like it was loading I didn’t do anything OK, so let’s just, for grins, print this out

Print Is loading Oh, wait, no That works, but we’ll also just print the loading value because that’s kind of where our source is And where’s our output? Well, those are things Let’s do hot restart just to try and clear the cache here That’s great Oh Hm Did our error catching go awry? EMILY SHAK: Are we seeing any error messages? EMILY FORTUNA: No Then again, we did delete that row [LAUGHTER] That’s great Let’s try starting afresh EMILY SHAK: We dream too big EMILY FORTUNA: Yeah, we do [LAUGHTER] Well, all else fails, we did get our stream working, and we have the beginnings of this Yeah But gosh OK, look at this So animator switcher, duration is loading That all looks reasonable OK EMILY SHAK: OK, so that worked, but it didn’t show the loading And are we seeing any prints? All right, so that’s not updating like we think it is EMILY FORTUNA: Yeah This is not getting– it’s not firing Sigh OK Loading tabs count is clearly not doing– is not what we think it is Let’s take a look at it Well, that’s an exciting function, [INAUDIBLE] class EMILY SHAK: Is that just always creating one with nothing? I mean, what’s that 0 feeding into? EMILY FORTUNA: It’s value notifier So we’re saying the starting value is 0 It’s extensive value notifier, which is just a little thing that pulls– EMILY SHAK: Oh, but it will update with a different value EMILY FORTUNA: Yeah But the question is, who’s updating it? So find all references Loading It’s passing it in there to a Hacker News tab Is loading So let’s look at Hacker News tab Where’s the constructor to this thing? EMILY SHAK: The Hacker News tab constructor? EMILY FORTUNA: Oh, there we go Loading tabs count Final Oh, here OK, refresh EMILY SHAK: Why are we notifying the listeners before we change the value? EMILY FORTUNA: That’s a very good question Let’s move that up Yes, it seems to– wait, or notify it here too, though EMILY SHAK: Also, yeah, I’m confused about why there are two notify listener calls in here EMILY FORTUNA: That feels very incorrect EMILY SHAK: It feels like maybe we just need to get rid of the first one EMILY FORTUNA: Yeah, I think you’re right EMILY SHAK: Because everything else is changing EMILY FORTUNA: OK So I’m going to do a hot restart again to blow away my caching It’s still not updating and I’m not getting a print statement Grrr EMILY SHAK: Oh, well, I’m noticing that we’re incrementing and decrementing it EMILY FORTUNA: Oh, my gosh EMILY SHAK: Do we need to be notifying listeners every change? EMILY FORTUNA: I have never used notifier listeners multiple times in a single function EMILY SHAK: Yeah But I guess, since it’s asynchronous, it kind of makes sense, if we do it when it’s up and then again when it’s down I’m wondering if we need to move that call below the decrement of it, and then also have another one that’s right after it’s been incremented EMILY FORTUNA: Yeah, so the way it was originally–

EMILY SHAK: It feels strange, though EMILY FORTUNA: It was like this We set [INAUDIBLE] to True Noti– but wouldn’t you put it– oh, whoa Why wouldn’t you put this below that one, and this below that one? EMILY SHAK: That’s what I’m wondering EMILY FORTUNA: Let’s try that Let’s do a hot restart Oh, fun things Field host lookup Good grief So we’re getting that information there? Interesting that we’re– let’s see Socket exception So we need to– instead of just checking for the 200, we need to do try on socket exception And I want to do on socket exception or if the status code is not good But I don’t know that we can do that We could throw another socket exception That seems really bad and dumb though Fine I’ll just– can we make this a– let’s make this a function The error function And then we’ll just say on socket exception error and if [INAUDIBLE]– oh, gosh OK I don’t like that code EMILY SHAK: Yeah It’s also not really the kind of thing that we are going to know if it’s working EMILY FORTUNA: Right OK So we changed some stuff Let me take out my drawer thing to see if, when I move those notify listeners, it still works as we were seeing it before EMILY SHAK: OK EMILY FORTUNA: And then we can– I know we’re running out of time a little bit So I want to– but we can at least make some progress So let’s cut this Or I guess we’ll leave it because we need to follow up about the bug report EMILY SHAK: Mhm EMILY FORTUNA: I will just– let’s command backslash, good that Oh, return OK, and hot restart again What have I done? Oh, I didn’t comment that out too Phew EMILY SHAK: So we’re still seeing a drawer EMILY FORTUNA: I still have a drawer EMILY SHAK: Is it– wait, where are you building the Y Combinator thing? It’s under this drawer argument Is that a problem? EMILY FORTUNA: I thought it should be OK, but– OK, let’s– EMILY SHAK: What if we were to put that under the leading argument? Because I’m wondering if leading is just a way to have something there that can do anything And we could have a drawer widget that builds there, and then maybe that’s the same kind of thing EMILY FORTUNA: True EMILY SHAK: Maybe that’s why it hasn’t been working EMILY FORTUNA: But why is drawer funky? We should read the documentation OK, so that works as we– it animates as we expected When you– that first time EMILY SHAK: OK EMILY FORTUNA: Because it’s loading So let’s take a quick– so I know we are running short on time Let’s take a quick look at the drawer documentation and we can– EMILY SHAK: I actually have it open EMILY FORTUNA: Perfect We can plan for what we’re going to do next time EMILY SHAK: OK EMILY FORTUNA: Let’s see [INAUDIBLE] design

EMILY SHAK: Oh, OK, a drawer class– no [INAUDIBLE] Interesting Oh, so this expects a lot about what its children are EMILY FORTUNA: Mm EMILY SHAK: Though it may be that it works without those EMILY FORTUNA: Yeah EMILY SHAK: And then there’s scaffold.drawer, which is what we’re using So a little hard to say what scaffold is expecting about what’s behind there But if you can use scaffoldstate.opendrawer to open it, then that must be at least something that is openable It might be imposing a drawer widget in some way EMILY FORTUNA: Oh, so we’ll do one more thing Let’s test– let’s make this a leading EMILY SHAK: Right EMILY FORTUNA: Yeah, which is what you’re saying How do I undo? Is it this? EMILY SHAK: No, it’s the same one Same command EMILY FORTUNA: Oh OK EMILY SHAK: It just toggles between them And then I think if you have some comments and some not in the block, then it adds another comment to everything EMILY FORTUNA: Yes, I saw that before OK, so let’s make this leading It doesn’t like that because– EMILY SHAK: Have you already defined leading? No Is this not inside the scaffold? EMILY FORTUNA: That might be dangerous Let’s see Leading Oh, it’s supposed to be App Bar Well, that’s a good start I’m a little scared about doing this, but here we go Leading– phew Oh EMILY SHAK: OK [LAUGHTER] EMILY FORTUNA: That’s a thing EMILY SHAK: So what did we expect to be there? EMILY FORTUNA: Oh, wow OK, so drawer is doing a lot under the covers So it is– because it is not loading, it is showing us a drawer But there’s something about scaffold that knows when to put the drawer thing– I think scaffold must be hard-coding that little hamburger menu Because this is showing us literally the drawer EMILY SHAK: Yeah I wonder if what we need is to have this be an icon button or something And then when you press it, we do the drawer operations manually EMILY FORTUNA: Yeah We should– OK, so let’s just put a little comments as a to-do EMILY SHAK: Yeah Can I see if, at least, the– EMILY FORTUNA: Oh, yeah EMILY SHAK: –loading thing is working? EMILY FORTUNA: So let’s do refresh or restart EMILY SHAK: It was going to be so good We’re printing a bunch of 1’s here though EMILY FORTUNA: Yeah EMILY SHAK: So are we not updating when it gets back to 0? EMILY FORTUNA: Oh, maybe– oh, yeah Oh, maybe my thing is wrong, although I would think it should be– it’s only 1 EMILY SHAK: Did it ever print a 2 up above? EMILY FORTUNA: No, it’s only that EMILY SHAK: Oh EMILY FORTUNA: It never printed 2, never printed 0 OK, so to-do’s We’re going to have– let’s– to-do Loading value– why is it never not 1? And then make a separate to-do EMILY SHAK: I mean, interestingly enough, it did show the drawer before we hot restarted So at some point, that value was 0 EMILY FORTUNA: But it wasn’t being notified EMILY SHAK: I’m wondering if we’re not notifying about the change back to 0 EMILY FORTUNA: And yet, we set that thing again Where was that? That was in– change the value This is a question for Phillip He is the– EMILY SHAK: Yeah, I want to understand this refresh function better, if there’s some reason that the notify listeners were where they were EMILY FORTUNA: Yeah OK, so make an icon button EMILY SHAK: That opens up a drawer? EMILY FORTUNA: That opens a drawer because scaffold hard-codes a drawer right here OK EMILY SHAK: And then make a whole Favorites page

EMILY FORTUNA: Yes [LAUGHTER] EMILY SHAK: That one’s maybe a couple episodes out [LAUGHTER] EMILY FORTUNA: We’ve got our work cut out for us All right, so thank you so much In summary, what we did was we cleaned up our– oh, look, the Favorites page is there again EMILY SHAK: Great Did it– when? Did you– EMILY FORTUNA: When I saved and it hot reloaded Because I guess the value is 0 It’s not being– so that’s– that value notifier is functioning strangely It’s not notifying every single– EMILY SHAK: Yeah EMILY FORTUNA: I think it’s– I wonder if that notify listeners is getting optimized out so it gets called– is that getting compressed or something? EMILY SHAK: But you would think that the second one, then, would be the one that takes precedence, right? EMILY FORTUNA: OK, wait Let me test one more thing before– I keep trying to wrap this up All right, let’s move it back to where it was Let me get diff or get status EMILY SHAK: I mean, they were both just moved right above where they are, I think EMILY FORTUNA: I know I just want to check because I don’t trust– I don’t trust myself EMILY SHAK: I do have the code open on my machine EMILY FORTUNA: OK Yeah, you’re right It’s up one line each one EMILY SHAK: OK EMILY FORTUNA: So Hacker News API x OK, let’s do hot restart OK OK, so the notifications is not what we think Other trick, so I can see– get blame Oops I copy/pasted So we know who to ask Filler EMILY SHAK: It’s a pretty clear filler [LAUGHTER] EMILY FORTUNA: Listeners Yeah, all right Philip, we got some questions for you So in summary, we fixed up the database stream EMILY SHAK: We filed that bug EMILY FORTUNA: Yes, we filed a bug We delved into drawers and learned a little bit more about how they work We got a little too tricky for our own selves EMILY SHAK: We may have ended with more questions than answers [LAUGHTER] EMILY FORTUNA: But that just gives you something to look forward to for the next episode Yeah, and in theory, what we want to do is we’ll have this drawer that can swap between the little three lines for a dropdown menu and the Y Combinator thing But the loading tabs counts was not doing what we expected, so we need to investigate some more So stay tuned on this exciting cliffhanger ending [LAUGHTER] There’ll be more to come See ya next time EMILY SHAK: Thanks for watching [MUSIC PLAYING]

You Want To Have Your Favorite Car?

We have a big list of modern & classic cars in both used and new categories.