Good morning, students. This is Wednesday morning. I wrote you Sunday saying, hey, sick canceling class. But I'll make you an Async lecture. I feel like I'm two days behind on that, but I keep my promises. Let's do this thing. Last time we were making a survey app. I wanted to finish it as just a little bonus lecture that'll add to the things. What do I mean by finish it? Honestly, I don't even remember. But that's okay. I know that I want to do a couple of things here. I want to have two terminals going. If you are installing the Firebase command line interface or whatever, fine, you can just click on it and have it going twice. For me, I'm in my own terminal, which I use every day in getting the fire based tool chain going. I can take Firebase and it will, I don't know what usage. Okay. The reason I want two terminals is I want to emulate my whole set up here. So this is going to act as like a local server, as if I was hosting it 5,002 I must be emulating a couple other things. Yeah, sure enough. I do this for real products or whatever, that will be today's flag. Okay. Okay, so we have this silly little thing and it has an open, let's see if we can't get to the actual firebase database here. I think the place we left off is that if I go into the database and like manually open and close it and things like that, I can totally get to in class FP real time database survey votes. Okay, great. So I've got some anonymous voting. My votes are not updating. I'm not rendering which vote I've chosen although I am with a CSS class. Remember correctly? Actually, I thought that would that, yeah. Okay. That's that's me logged in. That's my unique ID. Did I get a different unique ID? Yeah, I have a different unique ID though. Anonymous authentication, you get what you pay for. Okay. All right. So let's change that from close to open. If I'm right, maybe if I refresh this vote so far. Now this one, we'll have added a second vote. And I'll see that item two has been selected. Something along those lines here. I'll see that zero index strings or whatever, all that stuff is fine, but what are the little dumb things that are left here? Let's go take a look at the code here. I don't have to do this, I totally can whatever little for school and stuff, user ID render status. Okay. Some of the things that were done, I don't have differential behavior and I have this in my notes from Friday. Let's go webcast Fridays. Okay. We haven't made our buttons pretty We have updated. It's about where we leave off. I don't have any differential behavior for an admin, the starter stop or like put text values in. We totally did abstract to have options, maybe what I'll do here is options. How did those look? I had literally just an array, BC DE. And that's exactly how fire based arrays work. Okay, so let's do that. Let's add a little key that has like options and we'll go like zero. I'll, I'll make it like little, I don't know, fruits or something. Banana come quote, gosh, dates and the plan of fruit. Fine. All right. So I want those to show up on my buttons here. And I also want to highlight I want to make beautiful buttons and I want to highlight that. Okay, the other thing I want is how do I do admin stuff? And that might be more interesting to you. How do I do that? I've got some dumb ideas, we could try. Let's first get these options. Let's not do them. Let's do just a more normal person text. Okay? I have options here, and I'm reading these things in there and we're making all that stuff here. I have this, I've got a votes listener. The votes listener happens. This is the part that's probably most new and important to you all, is this line 68 here. When this happens, we're going to have the votes come in. I get a Json. Object. I check to see if yours is in there, and I highlight it. If you can, then I write it this way. And you can't write it that way. Now this part, I want that to actually be a listener on the can vote or not. Here's how I'm going to do that part. I have a listener on the surveys status. All I think what I'll do is I'm just going to take this little thing here. I think I'm going to move it into a different callback here. When I get a vote, I'm just going to highlight yours with the vote. I get this. What I'm going to do is I'm just going to say update status. I'll do the same thing here. Update status, I did want to know the number of votes. If I'm going to do an update status here, the survey status has open or closed. And that's going to do something that has the can vote as a global. What's not a global here is my votes screw. I'll just make it a global. If I wanted to make it infinite global, then I'll just say v equals an empty object or okay. So now that means that votes will be kind of a giant object. And I should maybe preserve that by saying if, if somebody deleted all the votes or something like that, I'll still make it an empty object 0. That means that I'll never return here. That's okay. Okay. So update status can now just refer to global. What this is really about, it's like the consciousness. So if my votes update, then I'll update the status. If my status updates, I'll update the status. Okay, now I've copied, I've cut the lines that matter here. Hopefully I didn't destroy them. But we'll just say update status equal to anonymous little function here that does these things. If can vote, we do this, otherwise we do that and this will just update this HTML tag, the guy that has this ID. We'll either say votes so far or they'll say results. Now we can change the status and it'll update in real time. This was re, factoring out the update status. Things happened when I wanted to. Okay, cool. That was one nice to have. Well, yes, options. Options. Options. Let's do the same dumb trick. This might be an anti pattern, you know, but I just posted that like getting things done kind of thing. And so tell you what, How about I do this, how about I make the default options this when we kill that. Okay, I've got these cool buttons with click listeners. This is all inside of render. Okay, fine. Render is going to set the button thing. Okay. Yeah, render me is just going to work from the options. That's fine. I think I can render me whenever we want. Right. Render actually, that's a good question. How sensitive is render render me on off state change? Maybe I engineering render me to be called over and over and over again. It's going to clear out in, it's going to add a button wrapper and then it's going to add the buttons based in the options. Then it's going to make click listeners for all the cool buttons the click listeners are going to set my vote. Highlight yours is a little utility inside of there. And make results is a little utility inside of there. Oh, this thing uses make results. Let's make results out of this. Maybe highlight your out. I don't think these need to be contextually nested inside of this thing. Let's move these up here, so highlight yours is just going to work off of CSS selectors and make results. It is just going to work off of CSS selectors. In that way, update status is also transcendent. I think it's just me being in a different mood today than I was on Friday maybe. But I just have to be consistent. Okay, so this is my vote listener. I don't want to have a bunch of these. Like I don't want to have like 50 of these listeners if I call render me over and over again. Let's alli, I want to delay the options, right? So the question is if I want to read these options from the database and I also want to make sure that you're authenticated. I think what I'm going to do is I'm going to call render me once I have new options, I'm going to make another request to these new options. And I'm actually going to do this as a once request. Here we go. Once I have logged in, then I'll go fetch the options. The way I do that is a once instead of an on. And what that'll do is say, hey, once you're logged in, go fetch what the questions are. Right now. Now we'll say options equals SS, stop Valmy then rendered. Honestly, if that was empty, this thing would totally be crashed. I think that probably is obvious. Let it crash sometimes it's better to let it crash to know where if things go wrong. Okay, that's going to call, that's going to update the options. I've definitely got an anti pattern going on. Now, one thing I do want to do this, I feel like now I could actually do that as like I don't know object values of options length. Now I could maybe just have two options, or three options, or five options or something like that. Whatever length that is that will go that far. I think I'll be cool, I'll be cool. I could make different lengths of options and just say like, yes, no or ABCDE. Hopefully it's not too much for creep or something. Okay, cool. So that's a lot of changes for me. Let's just see that I can see some fruit, you know, refresh this. Yes. Apple banana quote dates. My votes are going to be like a little bit wrong dish. Okay. And that was working, so that was just give me a different indexes and things or whatever. And now, if I set this to close, what results do we see when we're closed? We see three. Okay? Now I'm going to have to map back to these options, things like that. I also want to say like apple zero, banana zero. I could improve this results a little bit. If I go back to open, I think that this should just say votes so far too, now, that's at least real tiny. If that goes open, closed, I'll see votes so far, or the results. The results are hard to understand. Now that we have pretty options like 0131, that's not human useful. Let's make that human useful real quick. All right. Human useful. Well, that's cool. The nice part is that we utilitize, make results is just here I have the values of the vote array results. Okay, so let's just Jason string results is the lazy part. So let me just console log. I guess I know what the results say. At this point I have an options object. Which maps to apple. I have a results object which maps to one or two or whatever. Okay? What I need to do is I need to like parse this string zero into a zero in order to look up the apple or something like that. Okay, Let's say, well, we'll let you know. I'll call it results string thing. Yeah. Okay, How about this normalize equals this and then let's go like four. Let equals zero less than object values of options length plus let me go through how many option lengths I've got. And then what I want to normalize to is like I want to normalize me to kind of be an object that says like Apple to you. And dates for the options that don't exist. I want to put in zero. And if the options that do exist, I want that. Let's try this out. I'm going to go through each one, pretty key, equal options, okay? That should be Apple. And then, well, let vote results equals results of this is the part that's a little wacky. Results like a string of zero. I don't know, that's not like an obvious thing. I should parse it somewhere else that I get like an in zero or whatever. So I've got a little bit of like type juggling here, which is the exact thing that would either make type script awesome or suck. Because the reality is that it came out of HTML, so it came a string instead of an in. Now everything would break and I have to spend an hour debugging it, but it's easier to maintain or let me have the flexibility, I'll just do it. I think what I want to do is convert an integer into a string. There's a couple of ways I can do that, and I want to do some testing. To do testing, I'm just going to go to any website ever and I'm just going to say x equals zero. And I'm also going to try like string x equals zero. I want to have something that can work on either of these and send them into a thing. I think I could say int two string. All right? Maybe I can do string x, two string s. Okay? I can say two string and that'll work either way. All right? Let's say oh, no. Yeah, this is fine. That's okay. And I'll say results of or zero. All right? So this is a little bit wacky and saying if this thing has a string that points to two, I want the two. If this has literal zero that points to two, I want the two. And if you don't have either of those, I want this is the thing on the left is then do the next thing. If that's null, Now zero is falsy, but I don't care. I'm going to get to zero. Okay. Now I can say, normalize me pretty keyless, All right? That was a little bit of nonsense work. I could probably even make a table or something like that. Yeah, what do I want to do here? Results supposed to be returning a string version of this, but that's not very HTM LE. Maybe I wanted to return table or something like that. How does the make results get called or get used? It's just like that. If I take away the word results and I just make this literally make results, then now this can be either HTML or an element, or a string or whatever. Now, this will just do its best guess, which means I actually just make a whole HTML table here or something. Let's try that out. We'll say result. I have a little habit that if I've got an element on the page, or jquery element or something like that, I'm going to give $1 sign as the first character of the variable that lets me know that this is a special variable. This is pretty silly, but what I'll do is then just say, okay, I'm going to do result here. I'm going to make a table row with a column that will have pretty key. Now I'll make another column that has the vote results. I don't need that normalized object anymore. That's okay. It can just like exist. I will allow you to exist in my kingdom. Now I'll return result like that and that'll be like a literal HTML. This is me making an HL object off screen and then I'll add it to screen later. That's a pretty useful trick for getting around the binding problems and stuff, okay? So making a table, going through each key, making a row out of it, pushing that in, et cetera, Okay? Yeah. All right, so let's see how that looks here. Now look at that. Okay, cool apple one banana cut dates. I can add some CSS to that or whatever, something like that. I could add a frigging header and things like that. You can do. Table generator, look at that were a beautiful thing. What am I looking at? First rows, table header, how to use it. Table food table. Okay, this is like a fine, that's see, yeah, there we go. Yeah, that's good. That's good. That's almost salmon. Some more salmon. How about this guy? Okay. Okay, that sounds good. And here I set number of columns or something. Yeah. Okay. Head Tr0x, it's all this. Okay. I think I can just steal this CSS here and give it some classes in C. Okay. That'll be fine. They do have a T body, Okay. Okay. Okay. I can move that. So let's just do some crap like this. I wonder, I wonder if they're like, let me just include the whole style. I think I'll just work. Maybe this. I don't know if it'll work. We'll see. So like I just include style in my Jquery and add it. Got the styles there, there, okay. This belongs in a back tick, right? Belongs in a backtick. I now want to say body table. I'm just going to have, I want to say just two rows and this would be like this is a survey choice and counts. I don't know if that conveys is that the word? Like what were my options? Options, yeah, that's fine. Option result candidates. I just know what I'm really curious about is, does this just work? I have no idea if that'll work, but it'd be cool if it did. All right. So now I need to adjust this a little bit. Just say result to find body pen. They also kind of had some CSS classes they were leaning on here, which is that T D gets this class. So let's do that. Okay. All right, let's just see if that works. Is a break. Does work. Is a beautiful. Okay. I don't think I got the CSS like it's there, although I don't see the color in there either. Maybe when they said theme, that's okay. That's all right, that works. Candidate result. Apple banana, that's bold. All that kind of junk like that. We're going to get the themes. I had a theme, maybe I need to say generate with a theme. There we go. There's my colors, I'm just going to steal. Um, that's pretty cool. I get to throw CSS in the middle of my like Javascript thing there, whatever. It just shows up in words. Look at that, all right. All right, beautiful. Okay, cool. Almost time to like shower or no return for a class. This is totally working off of those things. Open. Go back to open now there's going to feel like vastly disappointing the boat so far. That's okay, but it is real time. Okay. All right. So now I can make the buttons prettier. We'll do that. Never. How about a differential behavior? One of the things I was thinking on that is I could Let's make just like a quick little admin page. Now I configured this hosting that 404 is the file doesn't exist, is mapped to the same index study. I'm going to grab more coffee because that's all important teaching. So what I'm thinking I'll do is just have a secret page. It's secure, right? Like this is not a thing where, you know, nefarious students can totally go mess with things or whatever. Yeah, absolutely. The case I have in mind is a student group that needs to do their votes or will they get silly? Sure, they can, but inevitably, they're all on the team. Somebody will get chastised, and their desire not to be kicked out of the group will cause um or something. I probably, yeah, the more likely a troll is to exist, the less likely you want to use this version of it. But whatever, we give up some security in order to have very quick ease of use with no almost entirely anonymous. Okay? What am I talking about? I want to do a cute little thing. Which is to say, if you are trying to get to the admin page or something, then I'll give you a slightly different view, or I can set the options and start or stop the survey. I'll probably still want to see all the rest of the second. I still want to see the number of votes and things like that. If I'm watching this as an admin, I just want to have an extra little thing at the bottom that maybe I'll just hide. Id equals f. I'm going to hide that. Say class equals hidden. All right, and this silly little trick, no security at all. Again, and I know we'll say hidden display, anything I add, the hidden class will just go away. Now the part of this that is the most threatening to me being to class in time, that is a variable number of options. One, Let's just make a couple of them. Start survey, study, survey. All right? We'll just say like options. So maybe I'll make a div that lets me set some options. Okay? And maybe I'll say button I, D. Add option button ID equals removed option. Okay. This is going to be a little bit crappy, but I think I can do fine option value. Yeah, this will totally be unintuitive to use, but that's okay. This is an admin name option here, okay. Not going to be winning any award for this thing. All right? And I'll make options just like Read only. This will end up as like Read only results. And I'll just manage it all through these four buttons. Okay, So then what I can do is, okay, if the survey is closed, then we can reset the option. Now, changing the options while somebody is watching is a little bit wacky wrestling with that earlier. I'm too many mental leaps ahead and I definitely need to a shower before a class. Let's just wire up, start and end, Step one, how do I know that this person is at my secret page? You know what, might be fun, really? Okay, one, if I'm at a page and I'm like synthesizing my existence on this page, what I can do is say documents location, Path. Oh sorry. Documents, location, half name, name. Okay. So I can sketch that. I could honestly even set that to like a secret value or something like that. You know that. Only the admins. No. And so what we'll do here is just say like if document location do half name dot match admin, all right? Then we will say admin remove class. All right. So that's a dumb little thing here where when I refresh this page, if I'm on admin, it'll now have these extra little buttons at the bottom. And if I'm anywhere else it won't Okay. They're there. And now I can wire it up as if they're there or not there or whatever. And it's really just a visual illusion. The security totally security by obscurity, that kind of thing, whatever. And I should absolutely, you know, put some spacers here or something. Okay? All right. There you go. So there's my admin page. Okay. And now make results of votes updating the options. Yeah, I see. I did make this as a once, which means that if I update the options, I'll just need to tell everybody, you know, the options to reset. Now, what would be the problem with that? You know what, I could probably be fine if I just have like an off value. All I was really worried about was zombie listeners. Um, I'll make this a little bit funkier and we're just going to say like, you know what, If you had any listeners in this thing before stop. If you had any listeners on this class before stop. That was my biggest concern, is that I'm going to end up with zombie listeners. And we're listening to the databases all over the place, whatever et cetera. Now what I could do is change that from values to an on values. Now, every time the options get updated, I'll re render the survey, which is cool. Okay, The results will get a little bit wacky from the previous results. You know, there's almost like a third state that sucks, but we'll deal with that in just a second. Okay? All right, so now let's just make the admin functionality just right up here at the top. Survey survey. Start survey on click I Think what I want to do is say Firebase database. I want to do two things at once here. I want to clear the votes and I want to set the status to open. That's all I want to do with that. This was what's my key surveys surveys, status database survey. So I think I could just say removed and firebase database survey status set to. Okay. Cool. So I should do that now. End survey. Okay. Now I do not want to remove the votes, so that's fine. And we'll set that to close. Okay? Cool. All right. All right. Add an option. All right. So we'll say add option. Now this is a little bit wacky, is super wacky. Options is being read from the database. Like my option value is totally coming down from the database as this array of things, okay? The options are 01234, whatever. I think what I could do, I'm just going to make this baby stack. When you click the ad options, I want to do a few things. Can then I'm going to alert you and say, hey, don't change options mid survey. You can vote none of that. All right. Now we'll say like option equal. And I'll read this from this input box, option value, I'll say les. If not new option, then I'll alert you, say hey, please provide an option that's just going to harass you at this point. Now I cannot vote and I do have an option to add. The question is, what is the ID of that thing? I believe that I can say I equal objects, values of options, that will be like the next value. Now I can say fire based database left, survey options, child set, It's new option, that's a little bit wacky. But basically saying, hey, you've got this object, how many keys are in the object? I do want to make sure that if options gets totally obliterated, which we're going to allow to happen with the next one. That when I get those options down my option, let's get a little spaghetti. At this point, I said before I wanted to fail. Now I want to fail. Now I want to be an empty object. Object at values will give you an empty array, and the length of that empty array will be zero. And that means that my first option will be zero. A option, okay, a little bit wacky. You can listen to this on half speed or something like that. It's going to be, I think that'll do the job. That's going to like set the child options. What? It's totally going to play hell on the results of the previous thing. That's going to change my options, but that's okay. Now we've got remove option, now we'll do the same trick, right? We'll say like let equal object values of options length. This side will say minus one. We'll say if I greater than equal to zero, maybe I'll just ask you or something like that. I'll say no equal a prompt Confirm, I think confirm is a data script command. We'll just ask you a question real quick. You want. To remove option and I'll say the value which is options. All right, if yes no, cool. Then we'll do the same kind of junk here, but we'll just remove that option instead. Okay, it's, you can only ever edit the last option which is wacky, you know, fine. Okay, but maybe functional. Let's find out. Okay, so if I remove option, we're going to remove option for egg plant. Yes, cool. Remove option? Yes. Move option? Yes. Remove option? Yes. Move option Yes. Now I'm going to add Yes as an option and we're going to add No as an option and then we'll start. So so far, yes. Okay. See all that left is just a little bit CSS to say which button I've selected and that'll be fine. So let's do that real quick. Like can I just Here's selected. Let's just like edit this in real in place and we'll say that selected. What do I want to do for this? I could, I mean, obviously I could say like order three pixel solid salmon. Yes. Yes, that, I mean done. Right. Okay. And then we'll end it and there was one vote for now. Fantastic. Fantastic. Okay. All going to do is just going to steal that. We'll just throw it in as like a single page, single page, Super simple in class survey with security of obscurity deployed at a real site. So now I think this is fine. We refresh this. We've got an admin thing. I cannot change my vote in the middle of the thing, but I can end it, start it, and votes result, et cetera. Um, you know, I should put a percentage of the class to go to that or whatever. Like do some map for me. But whatever I can do my own map. Okay, let's deploy this. Go here, which we'll see deploy. If I'm right, this now exists at survey dot survey. All right, cool. That is the promised a sync lecture. I'll see you all in about 30 minutes.
Async survey app part2
From Andrew Novocin September 20, 2023
29 plays
29
0 comments
0
You unliked the media.
Zoom Recording ID: 4159319948
UUID: 2AraofMVTpqtf3EE7mYzjg==
Meeting Time: 2023-09-20 11:42:26amGMT
…Read more
Less…
- Tags
- Department Name
- ECE
- Department Division
- Date Established
- September 20, 2023
- Appears In
Link to Media Page
Loading
Add a comment