[User] Please transcribe this text

[Assistant] These people are data analysts and did I already mention they are in high demand?


[User] Please transcribe this text

[Assistant] Whether you're a business owner, a marketer, or just someone who wants to understand the world around you, data analytics is an essential skill to have.


[User] Please transcribe this text

[Assistant] And although it's true that when we talk about data today, we immediately think of terabytes of data collected every second through the internet in complex machines and procedures. Data could also be the handwritten records you keep about purchases at your bake sale.


[User] Please transcribe this text

[Assistant] Or a daily log you keep of your blood pressure. It doesn't need to be complicated. When you structure and analyze your data in the right way, even simple data can become meaningful and help you to gain insights and make better decisions in the future.


[User] Please transcribe this text

[Assistant] To really capitalize on the power of data, we need people that can help collect the relevant data, clean and organize that data and analyze and visualize that data to uncover insights and help us make informed decisions. And that's exactly what data analysts do.


[User] Please transcribe this text

[Assistant] Even if you don't plan on becoming a data analyst, having a basic understanding of data analytics will be beneficial to you in many ways.


[User] Please transcribe this text

[Assistant] And to communicate data in a clear and concise manner.


[User] Please transcribe this text

[Assistant] Before we delve into all the aspects of data analytics, let's first define what data analytics really is. That's what's coming up next.


[User] Please transcribe this text

[Assistant] The question of whether age affects our political views is a tricky one. I think probably the most plausible explanation.


[User] Please transcribe this text

[Assistant] Is that people just generally become a bit more resistant to change as they get older. And I think also that they tend to perhaps become less idealistic.


[User] Please transcribe this text

[Assistant] So parties on the right represent a platform which is perhaps more favorable to the status quo.


[User] Please transcribe this text

[Assistant] It's perhaps more about pragmatism than it is about idealism.


[User] Please transcribe this text

[Assistant] It's perhaps more about pragmatism than it is about idealism.


[User] Please transcribe this text

[Assistant] And that might be more attractive to older people than younger people.


[User] Please transcribe this text

[Assistant] Microgravity is really challenging but plants are amazing. They can adapt to so many different environments and we call this plasticity because they can turn on or off their genes to really adapt to all sorts of conditions and that's why you see plants growing in


[User] Please transcribe this text

[Assistant] Different areas on earth, the same type of plant may look very different because it's adapting to the environment in that specific location.


[User] Please transcribe this text

[Assistant] Thank you all for coming. Thanks for the introduction. Let's get started right away. The title of my talk is The Soul of Statistics. Let's start with a motivating example before I tell you what I think the soul of statistics is. So Abraham Wald was a famous statistician and during World War II,


[User] Please transcribe this text

[Assistant] About trot, trot, trying to figure out where to put more armor. You know, they want to put more armor, but the armor is heavy and expensive. They can't just put armor everywhere, so wherever you put, put the armor. Okay, so I drew some airplanes here. These don't really look like bombers, but that's okay. Uhm, so.


[User] Please transcribe this text

[Assistant] Uhm, sorry, I didn't have a warning that there would be graphic violence here, so hopefully no one is too squeamish. There's another one, another one, another one. Bam, bam, bam, bam.


[User] Please transcribe this text

[Assistant] Uh, so these are just, I just made up some bullet holes on these planes. And these are the planes that they get to observe. Okay, just as an example. So they brought in Wall to ask, you know, where should they be putting more armor? Well,


[User] Please transcribe this text

[Assistant] The obvious thing to do is look at where all the planes are sustaining heavy damage and armor those regions more. However, Wald said to do the exact opposite. Look for the parts of the planes where there's very little or no damage on the planes that came back.


[User] Please transcribe this text

[Assistant] The reason is, so for this example, I protected the nose on all of these planes.


[User] Please transcribe this text

[Assistant] And so, what's really going on here? Well, what we're really interested in is the planes that we didn't see. Those are the planes that didn't come back. The ones that you actually get to see are the planes that actually survived well enough to return.


[User] Please transcribe this text

[Assistant] So, so, there's some statistical thinking in there. How do you learn about the planes you don't get to see? And, you know, that requires some statistical assumptions and statistical thinking about what do you do about the missing data, right? So maybe what if it looks like this?


[User] Please transcribe this text

[Assistant] This plane, we didn't get to see it because that's like the Achilles heel or the Achilles nose of the plane and maybe there's like, like a whole army of these like,


[User] Please transcribe this text

[Assistant] That we don't get to see any of them because they all died and we only saw the other ones. So that's where you put the armor. So that was the idea. It's a pretty simple idea in retrospect but easy to miss if you're not thinking statistically.


[User] Please transcribe this text

[Assistant] Okay, so that's an example of what's called selection bias in statistics. What we, what we know about is what we get to see, which is where the bullet holes are distributed for the planes that actually return. But that's not what we're interested in. We want to know about the planes that didn't make it back.


[User] Please transcribe this text

[Assistant] Okay, so how do we link those two things? That's a statistical problem. Now we're ready to say, what's the soul of statistics? I won't keep you in suspense. Conditioning is the soul of statistics.


[User] Please transcribe this text

[Assistant] That means conditional probability, for those of you who know what that is, if you don't know conditional probability,


[User] Please transcribe this text

[Assistant] All it means is that we're given information. We always have information wherever we're doing. It's all conditional on the information that we have and conditional probability tells us how to update our beliefs.


[User] Please transcribe this text

[Assistant] Based on information that we're able to observe. Every probability is conditional. And so that's the point of view here.


[User] Please transcribe this text

[Assistant] Whenever you have a data set, you want to think about how it was sampled. So this is just a picture that I'm not really going to talk about of a network, which is something I work on where


[User] Please transcribe this text

[Assistant] There's a huge amount of interest in networks these days, but a lot of that work ignores where did the network come from, how is it sampled, and that can lead to very misleading answers if you ignore the sampling, if you're not careful about what you're conditioning on.


[User] Please transcribe this text

[Assistant] And, you know, this is mostly Harvard thinks big, so I'm going to try to think really big, that this is not just the soul of statistics, this is everything, because


[User] Please transcribe this text

[Assistant] We wouldn't be, if what I said was not true, we wouldn't be here having this conversation. It's all conditional on a huge conditional probability calculation that we can't actually do of things that brought us to this room to have this conversation right now. Everything is conditional.


[User] Please transcribe this text

[Assistant] Okay, so here's another example. This is a longevity study from 1835. Lombard was interested in collecting huge amounts of data, a very impressive data collection effort, for how long people in different professions lived.


[User] Please transcribe this text

[Assistant] Okay, so I'll just give you a few, a few, I chose a few examples, that, that's a selection bias too, the ones that I felt like choosing because, because, because it's a short talk.


[User] Please transcribe this text

[Assistant] So here's the profession, here's the average longevity in his data set. So it turned out that the first or second longest living people in his data set were chocolate makers.


[User] Please transcribe this text

[Assistant] So I was very happy to see that because I really like chocolate. They lived to be 73.6, which, you know, lifespans have improved from 1835 to now, so that's actually quite good back then.


[User] Please transcribe this text

[Assistant] And, uh, this is not second on the list, but one that I was interested in was professors.


[User] Please transcribe this text

[Assistant] Lived to be 66.6, so I know it's a little bit sad, you know, I could have, if I had chosen a different career path, I could have lived seven years longer and had all the chocolate that I want.


[User] Please transcribe this text

[Assistant] There is a sample size issue here, which is, he only had nine chocolate makers in his sample. That's a very small sample. There are a lot more professors than chocolate makers in his study. But anyway, I want, let's go on.


[User] Please transcribe this text

[Assistant] 47.2, I was trying to figure out why is there this discrepancy between clocksmiths and locksmiths? What could explain this? I don't have an answer yet. One more that is of interest to all of us is students


[User] Please transcribe this text

[Assistant] Uhm, unfortunately I have some bad news for all the students here. In his study he found that average longevity of students is 20.2 years. So...


[User] Please transcribe this text

[Assistant] I don't want to be like, get this event off to a depressing start. I'm the first speaker and I don't want everyone to be too depressed to pay attention to the other talks that are coming up.


[User] Please transcribe this text

[Assistant] 20.2 years, you know, it's worrisome. Uhm, I recommend that if you haven't seen Steve Jobs' commencement address from Stanford 2005, I was there because I was at Stanford. It's a great talk. Thanks. And uhm, you know, about living it each day to the max and all that. Okay, but.


[User] Please transcribe this text

[Assistant] You know, 20 years old is a normal age for a student. Okay, so it's kind of obvious to see what goes wrong. It's a good example of looking at an extreme case. Because in the earlier professions, it's not obvious that there are all kinds of biases going on. But when you see the simple and extreme case of a student, you can see that the whole thing is very suspicious.


[User] Please transcribe this text

[Assistant] Okay, so usually it's a lot harder to talk to dead people than to talk to live people. And Professor Dench will be telling us about talking to dead people in detail. But this is one case where it's much easier to deal with the dead people because we know how long they lived. Okay, so there's a large amount of statistical survival analysis.


[User] Please transcribe this text

[Assistant] And statistics is regression towards the mean.


[User] Please transcribe this text

[Assistant] And it's everywhere. So just to take an example, if you're not familiar with this, take test scores. So you have a group of students who take the SAT. And then suppose that the ones who did really well take it again, and the ones who did really poorly take it again. So we're doing a selection, okay? Well,


[User] Please transcribe this text

[Assistant] Regression towards the mean says that we expect the one, the students who did really well on the SAT when they retake it, their scores are going to tend to go down towards the mean. The ones who did really poorly are going to go up.


[User] Please transcribe this text

[Assistant] There's examples everywhere. Uh, one of the first examples, I'm not gonna go through this data table here, but that's just for historical curiosity. Uh, Sir Francis Galton, who was a cousin of Darwin, was one of the first, or possibly the first,


[User] Please transcribe this text

[Assistant] How tall are their sons? Well, the sons are still pretty tall, but they are regressing towards the mean. Okay, and very short fathers, their sons tend to be taller, not


[User] Please transcribe this text

[Assistant] Not all the way to the mean, this is a regression toward the mean, not to the mean, but it's moving in that direction. That phenomenon is everywhere in statistics and in life, so if you have your eyes open to look for it, that's a good thing.


[User] Please transcribe this text

[Assistant] And so, uhm, I just wanted to quickly quote, uh, Daniel Kahneman, uh, because it's a beautiful quote, uh, about regression towards the mean. He said, I had the most satisfying Eureka experience of my career while attempting to teach flight instructors that praise is more effective than punishment for promoting skill learning.


[User] Please transcribe this text

[Assistant] And when he gave that talk a flight instructor objected, on many occasions I've praised flight cadets for clean execution of some aerobatic maneuver, and in general when they try it again they do worse.


[User] Please transcribe this text

[Assistant] On the other hand, I've often screamed at cadets for bad execution and then they do better the next time. So don't tell me that reinforcement works and punishment does not.


[User] Please transcribe this text

[Assistant] And Kahneman said that's a joyous moment because


[User] Please transcribe this text

[Assistant] What he, what he realized is we tend to reward others when they do well and punish them when they do badly. And because there's regression to the mean, you should say toward the mean, it is part of the human condition that we are statistically punished for rewarding others and rewarded for punishing them.


[User] Please transcribe this text

[Assistant] And, uh, so there are a lot of misconceptions about, uh, regression toward the mean that, that I, that I don't have time to get into detail of, but I wanted to get, do a quick little, little picture.


[User] Please transcribe this text

[Assistant] Illustrating a hypothetical thought experiment, what would the world be like without regression toward the mean? Because a lot of people seem to have the misconception that regression toward the mean would mean that


[User] Please transcribe this text

[Assistant] Everyone is going to be, you know, eventually converging to the same value. And actually, without regression toward the mean,


[User] Please transcribe this text

[Assistant] We need regression toward the mean in order to have stability in the population. So I just made up a simple example where suppose we have three people, three different heights.


[User] Please transcribe this text

[Assistant] And suppose each person has a child who's equally likely to be a little bit shorter, the same height, or a little bit taller. Okay, so I just gave them three kids each. A little shorter, same height, little bit taller. So that's the next generation. Then I just took that generation and just rearranged it. These are the same people. Now, same thing happens again. That's the next generation.


[User] Please transcribe this text

[Assistant] And then I'll just take one, one more generation. This is, this is what the population would look like without regression towards the mean. What you see is after only three or four generations, you know, you're, you're going to see giant, you know, ten foot people walking around and you have little, little, little four inch people, things like that.


[User] Please transcribe this text

[Assistant] That's what the world would be like without regression toward the mean.


[User] Please transcribe this text

[Assistant] I want to tie this back to this kind of personal perspective on teaching and research, which is something I call the conditional golden rule.


[User] Please transcribe this text

[Assistant] So this was a course evaluation I got on the Q-Guide a few years ago. Uhm, so, so someone wrote, it was a class, this is about Stat 110, it was a class that was designed by Blitz with the credo, I wanted to teach a class that I would want to take myself.


[User] Please transcribe this text

[Assistant] Unfortunately, I, I try to be logical, the logical conclusion from these two things is that I'm a masochist. Uhm, so let me just...


[User] Please transcribe this text

[Assistant] So let me just tell you what the conditional golden rule is and then I'll stop. This is my philosophy of teaching in a nutshell.


[User] Please transcribe this text

[Assistant] Conditionally I'm having the same interest and background and knowledge. So I just try to do the conditional golden rule. I'm trying to follow it right now and giving this talk. And if I failed, uh, blame the conditional golden rule.


[User] Please transcribe this text

[Assistant] Or blame the fact that conditional probability is hard, as we see in Stat 110. It's hard, but it's worth thinking about. Okay. So I just want to thank the organizers, and thank my colleagues, especially Karl Morris, Xiaoli Meng, and Dave Harrington, and all my Stat 110 students and TFs, and all of you for coming. Thank you.


[User] Please transcribe this text

[Assistant] Even though I apologize for calling her fat, Genie was trippin' all night.


[User] Please transcribe this text

[Assistant] This guy caused a car accident and I was like, you idiot! You can kill people by driving like that!


[User] Please transcribe this text

[Assistant] I told the teacher that I didn't finish my homework and he was like, I'll see you after school.


[User] Please transcribe this text

[Assistant] Mount Everest's summit is unquestionably the highest point on Earth. But from a climber's perspective, it doesn't always feel that way. Thanks to the physics of our atmosphere, at times it can seem lower than its neighbor, K2.


[User] Please transcribe this text

[Assistant] Climbers often carry supplemental oxygen because there's so little air to breathe. This is because, as altitude increases, air pressure decreases. There are a couple reasons for this. For one, because they're further away from the core of the planet,


[User] Please transcribe this text

[Assistant] The air molecules higher up literally feel less pull from gravity. But also, the air lower down has more air sitting on top of it.


[User] Please transcribe this text

[Assistant] So there's more physically pressing down on it than on higher-altitude air.


[User] Please transcribe this text

[Assistant] Thanks to the physics of gases, we know that decreases in air pressure are proportional to decreases in air density. So the decreasing pressure as you ascend means, quite literally, there are fewer oxygen molecules in any given volume of air. But unfortunately for us humans, our lung capacity needs time to catch up to this change.


[User] Please transcribe this text

[Assistant] So the higher up a climber goes, the fewer oxygen molecules they take in with each breath. The thing is, while elevation is a big factor in air density, it's not the only one.


[User] Please transcribe this text

[Assistant] So the air pressure atop Everest doesn't just depend on the peak's height. It turns out, different weather conditions can cause the air pressure on Everest to vary up to 34 hectopascals. That's like losing 737 meters of height!


[User] Please transcribe this text

[Assistant] And since Everest is only about 250 meters higher than K2, sometimes K2 feels higher than Everest. Everest's air pressure changes are due to atmospheric circulation.


[User] Please transcribe this text

[Assistant] That's just a fancy word for the way air moves around our planet. It's the same thing that affects our daily weather and climate. So basically, it's just like how, at sea level, we can experience high pressure fronts and low pressure fronts. But if you're a climber, particularly one climbing without supplemental oxygen,


[User] Please transcribe this text

[Assistant] This means your experience on Everest could vary a lot depending on how high the summit


[User] Please transcribe this text

[Assistant] In fact, researchers found that all climbers who successfully climbed Everest without oxygen did so within a relatively narrow air pressure range. That's not a huge surprise, because air pressure tends to be higher when weather is good, and climbers tend to wait for parts of the year when there is better weather.


[User] Please transcribe this text

[Assistant] But this also means that climbers usually summon Everest when it feels like it's at a lower altitude. And to put it another way, climbers haven't really experienced the full height that Everest has to offer. And they probably won't going forward. See, air pressure tends to increase when temperature increases.


[User] Please transcribe this text

[Assistant] Because when air heats up, the molecules in it start to move faster and collide with each other more. Well, research shows that the air pressure on Everest's summit has increased in the past decade.


[User] Please transcribe this text

[Assistant] Which is tied to an increase in temperature. But more importantly, a global temperature increase of 2 degrees, the goal of the Paris Agreement, would make Everest's summit feel about 120 meters lower. So, ultimately, Everest is probably going to get a bit easier to climb.


[User] Please transcribe this text

[Assistant] When it comes to the air, anyway. Thanks for watching this episode of SciShow! If you learned something new, we'd love to hear about it in the comments. And if you want to learn all sorts of new things all the time, be sure to click that subscribe button and ring the notification bell.


[User] Please transcribe this text

[Assistant] There's no better time to win than right now, heading towards finals week, just kind of, you know, shadowing on the horizon. This is good.


[User] Please transcribe this text

[Assistant] So Louise, you had a very good cook in the mystery box. This cook may not have gone quite so well.


[User] Please transcribe this text

[Assistant] Uhm, first, I'm gonna go through some terminology. Synchronous and asynchronous.


[User] Please transcribe this text

[Assistant] What asynchronous processing does, is let's say at the start of the day, she just places all of her orders at once. And throughout the day, she does all of her tasks, like cooking food, or disciplining the lecturers, or getting gains. All the while, the orders are being fulfilled one by one as she's doing her synchronous tasks.


[User] Please transcribe this text

[Assistant] Just like promises. Sorry, this thing is in the way. Just like promises.


[User] Please transcribe this text

[Assistant] Delete the entire like folder on your laptops and reclone it. And the reason why is because we restructured the branches a little bit and we, we don't, we just want to make sure that no one has any issues with like pulling random things. So the cleanest way to do this is just to delete it and re clone it. So.


[User] Please transcribe this text

[Assistant] Once you're inside of your Capbook React folder, uhm,


[User] Please transcribe this text

[Assistant] And this will essentially like delete the entire repo off your, off your folder. Alternatively, like if you have like.


[User] Please transcribe this text

[Assistant] You can just get cloned, uh, the same way that we did like, when we initially cloned.


[User] Please transcribe this text

[Assistant] So you can go to this like code thing, which has the URL. Uh, some of you might be using like SSH, but it shouldn't matter.


[User] Please transcribe this text

[Assistant] Can I get like, uh, like a thumbs up or something if you're able to like see Catbook react? Okay, I'll give everyone like, uh, like a minute or two more.


[User] Please transcribe this text

[Assistant] Okay, cool. Uhm, if you, if you have any trouble, definitely like feel free to add yourself to the queue and uhm, we can have someone help. This step is like pretty important because uhm, we want to make sure that all the branches are like synced. There's like some renaming that was going on, so.


[User] Please transcribe this text

[Assistant] The branch that we're be going, uh, on today is, uh, workshop eight. So first run these commands, get fetch.


[User] Please transcribe this text

[Assistant] Here we set hard and then check out the branch. Step one.


[User] Please transcribe this text

[Assistant] W a dash step one. And then because we just reclaimed the repo, we will also want to make sure that we run NPM install.


[User] Please transcribe this text

[Assistant] We can start our server in frontend as usual with npm start and npm run hotloader.


[User] Please transcribe this text

[Assistant] I guess like before I move on, uh, does anyone have any questions or like, is still like, uh, needs a bit more time to set things up?


[User] Please transcribe this text

[Assistant] The first thing that we're going to do for step one is, first of all, if you take a look at the, um, like the nav bar, you'll notice that we have like a new, uh, chat page at the top. So right now this chat page is empty.


[User] Please transcribe this text

[Assistant] Uhm, what we want to like see after this step is we want to be able to see who we're chatting with. So at the top we'll have like a header that says we're chatting with whoever and


[User] Please transcribe this text

[Assistant] Uhm, the way we're gonna implement the actual chat is by


[User] Please transcribe this text

[Assistant] Breaking it down into a single message component and a new message component.


[User] Please transcribe this text

[Assistant] So uhm, we added a new component called chatbook, and this chatbook is what's going to actually render the uhm, like the content.


[User] Please transcribe this text

[Assistant] Each message object has a sender, so that's going to be what's rendered like on the left and also some content, which is like the message itself. And so both senders and recipients are user objects and user objects are just objects that store like the information about each user. So that will just like have a name and also like an underscore ID.


[User] Please transcribe this text

[Assistant] The single message component is going to be what is actually rendering, like, a single message. So that information is encoded inside of a message object.


[User] Please transcribe this text

[Assistant] And then finally we'll finish off in steps 1.5 and 1.6 with implementing like, uh, uh, with putting the chat component inside of chatbook.


[User] Please transcribe this text

[Assistant] So this is just an overall summary of how we're going to approach this. This is definitely like, uh, like it seems like a lot, but we'll take this like step by step and we'll also walk through, uh, like all the code.


[User] Please transcribe this text

[Assistant] Let's go into new postinput.js because this is going to be uhm.


[User] Please transcribe this text

[Assistant] Uh, this is where our new message component is going to live.


[User] Please transcribe this text

[Assistant] We see that we want to populate, uh, we have some like to do's here. So we're going to start with, um, returning a new post input component.


[User] Please transcribe this text

[Assistant] So if you remember from some of our previous workshops, we actually used this component before, but just to like, um, review a little bit new post input is just a component that.


[User] Please transcribe this text

[Assistant] It takes that, uh, has like a state, which is like the value that the user is typing at the bottom of the screen. And it also has like a submit, um, and this like handle submit is a prop that's passed into the new post input component. So we can essentially do, uh, we can pass in a function that does whatever it wants, um, when we like press the submit button. So.


[User] Please transcribe this text

[Assistant] We can, we can take some of the syntax that was used earlier, uhm, for our new message components. So for new story,


[User] Please transcribe this text

[Assistant] And we want to set the default text, which is like the gray text that renders at the bottom.


[User] Please transcribe this text

[Assistant] And we can set the default text to be like new message and.


[User] Please transcribe this text

[Assistant] We can also pass in like the submit function so we can say send message. And.


[User] Please transcribe this text

[Assistant] So send message will take in as input, uh, like a value. And this value is just the state that we talked about that the new post input component is maintaining. So it's just the value of the message that's being typed.


[User] Please transcribe this text

[Assistant] And for now, what we're gonna do is, uhm, like it sort of shows in the demo, we're just going to console log the message. So we can console log value.


[User] Please transcribe this text

[Assistant] In the future, this, uh, this function is going to be used to like post these messages into our database. Um, but just for this step, we just want to make sure that everything is working properly so we can just like console log it.


[User] Please transcribe this text

[Assistant] The next step is to, uh, implement the single message component. So the single message component lives in single message.js.


[User] Please transcribe this text

[Assistant] Essentially what we want single message to look like is uhm, we want to have like a bold sender.


[User] Please transcribe this text

[Assistant] With like a colon and then also like the message itself. So.


[User] Please transcribe this text

[Assistant] We can do is like, we have some like pre-written CSS classes provided for you. Um, so.


[User] Please transcribe this text

[Assistant] We'll first wrap everything in like a container. So we have like uflex.


[User] Please transcribe this text

[Assistant] So the, like the details of like the CSS classes are not so important. This is mostly just to save time, but uhm,


[User] Please transcribe this text

[Assistant] Or another div with some more like pre-written classes. So this will be a single message sender. And also in bold.


[User] Please transcribe this text

[Assistant] And one thing is that we want to actually, uhm, show, like, who is the sender of this message.


[User] Please transcribe this text

[Assistant] So if you remember, this single message component takes in as a


[User] Please transcribe this text

[Assistant] Is uh, defined here. It's also defined in the code as well. But essentially the message object has a sender and the sender is a user object.


[User] Please transcribe this text

[Assistant] The user object has a name and this is what we ultimately want to render. So in order to render the name,


[User] Please transcribe this text

[Assistant] And a sender is a user object. So inside the user object, you want to grab the name. So .name.


[User] Please transcribe this text

[Assistant] And then, uhm, so right next to the, uh, sender name, we also want to put the message, the message content itself. So this has some more like pre-written classes, single message content. And, uhm,


[User] Please transcribe this text

[Assistant] Remember we can grab the message object with props.message, and the message object also has like a key called like content, and that is where the actual content of the message will be stored.


[User] Please transcribe this text

[Assistant] Instead of 1.4, we're essentially rendering both the single message component and the new message component into like one like actual chat interface.


[User] Please transcribe this text

[Assistant] So this chat component lives in chat.js.


[User] Please transcribe this text

[Assistant] We'll be, the first thing we're gonna do is we're gonna wrap everything inside like a container. Uhm.


[User] Please transcribe this text

[Assistant] This, uh, uh, like basically who we're chatting with will also be passed down to us with props. So if you look at like the diagram, we're getting the prop, um,


[User] Please transcribe this text

[Assistant] Chat data passed down to us into chat and chat data has a recipient as one of the fields. Recipient is a user object which has a name.


[User] Please transcribe this text

[Assistant] So we're chatting with, to get the chat data object, we want props.data and then


[User] Please transcribe this text

[Assistant] ChatData has a recipient, so chat.data.recipient and then .name because it's a user object which has a name.


[User] Please transcribe this text

[Assistant] And then below the h3 tag is where we want to render the actual chat itself. So we'll make like another wrapper around the entire chat.


[User] Please transcribe this text

[Assistant] Notice that like, we have an array of message objects that were passed to us via the chat data prop. So what we can do is we can, uhm,


[User] Please transcribe this text

[Assistant] Use this array to render like an array of single message components. So we're going to do this using the dot map function. So remember that obstet data gets the chat data component.


[User] Please transcribe this text

[Assistant] .messages will retrieve the array of message objects and then .map and


[User] Please transcribe this text

[Assistant] For each element in the array props that data.messages, we're rendering a single message where


[User] Please transcribe this text

[Assistant] Remember that our single message component takes in, uh, like a message as a prop. So we pass in message equals M and you might be wondering like,


[User] Please transcribe this text

[Assistant] What is this key prop doing here? Because it seems like inside single message, we're not actually using any like key prop and.


[User] Please transcribe this text

[Assistant] Essentially this has to do with the way that, uh, React like renders the page. So in particular, like.


[User] Please transcribe this text

[Assistant] Uh, the code that we use for rendering the list of single messages. And then the last part of the, um,


[User] Please transcribe this text

[Assistant] Uh, and inside we'll put a new message component. And if you remember the new message component, uh, takes in just the recipient as like, as props.


[User] Please transcribe this text

[Assistant] You'll notice that we're not actually using the recipient anywhere. Um, and that's just because we haven't, we're not sending any mess, we're not actually like sending any messages yet. So we don't like, basically we don't have a backend yet, but.


[User] Please transcribe this text

[Assistant] Eventually we will be using this recipient. Uh, when we're sending messages, we want to know like who we're actually sending them to.


[User] Please transcribe this text

[Assistant] So this is basically everything for step 1.4.


[User] Please transcribe this text

[Assistant] So the chapel component itself lives in chapel.js.


[User] Please transcribe this text

[Assistant] Uhm, this like array of test messages will also fill up some more like, some more like mock data in a bit. But for now, uhm.


[User] Please transcribe this text

[Assistant] We'll start by rendering the actual like, or like setting up the...


[User] Please transcribe this text

[Assistant] Uhm, the containers that contain the chatbook.


[User] Please transcribe this text

[Assistant] You might be wondering like why we're just like spamming containers and like the reason why is because like.


[User] Please transcribe this text

[Assistant] Um, but since we're only rendering like one thing right now, it seems like we're just like nesting a bunch of containers, which might be like a bit redundant, but eventually we will like be populating this, uh, these containers with even more code. So we'll have one more container for the actual chat book itself.


[User] Please transcribe this text

[Assistant] And inside this container, we'll be rendering the chat component.


[User] Please transcribe this text

[Assistant] Remember that our chat component takes in the chat data as props because that's how it knows what to render. So we'll do like, we'll create some like test data.


[User] Please transcribe this text

[Assistant] So we'll pass in this like test data as, uh, some data. We haven't created this yet, so, um, nothing will render.


[User] Please transcribe this text

[Assistant] And then to create our test data, well, we'll create it at the top of the page.


[User] Please transcribe this text

[Assistant] Remember that our test data has to be of type chat data, which has an array of message objects and also a recipient. So we can do like the recipient is some, something called all chats and messages is test messages.


[User] Please transcribe this text

[Assistant] We'll define all chat essentially. Right now we're just going to hard code that we're only like sending chats into like a global chat.


[User] Please transcribe this text

[Assistant] Eventually we will support, like in the next workshop, we'll support like how to send like DMs to individual people. Uh, for now we're just going to only implement like a global chat though. So let's define all chat.


[User] Please transcribe this text

[Assistant] Uh, remember that each recipient has to have like a unique like underscore ID and also a name. So we'll say ID is like all chats and then the name is all chats.


[User] Please transcribe this text

[Assistant] Uhm, maybe just to render like a more interesting like chat, we can add another message. So each message has a sender, which is a user object. So.


[User] Please transcribe this text

[Assistant] Let's add a, let's say that like Michael is responding to Kennen.


[User] Please transcribe this text

[Assistant] And let's say he's responding to Ken's message with like, me too.


[User] Please transcribe this text

[Assistant] So I'll, I'll hold all this code on the screen for like maybe 30 seconds so people can get caught up.


[User] Please transcribe this text

[Assistant] But again, just to reemphasize, uhm, what we're doing here is we're just setting up the data that, uh, oh, thanks.


[User] Please transcribe this text

[Assistant] Uh, we would be fetching from the database. This is exactly how it would look. It's just like a bunch of like JSON objects and like arrays. Um, but we're just like hard coding the data right now, since we're not actually fetching anything from a database yet.


[User] Please transcribe this text

[Assistant] Uhm, so, once we go to local 5050, uh, nice, we should see that everything is showing up.


[User] Please transcribe this text

[Assistant] The way that we set up this submit button is right now we're just console logging the message so we can test like the message. We press submit.


[User] Please transcribe this text

[Assistant] Uhm, we see that it, it does get consoled.


[User] Please transcribe this text

[Assistant] Okay, cool. So to get caught up, you can run git reset dash dash hard, and then git checkout, which are eight step two.


[User] Please transcribe this text

[Assistant] Inside of, uh, chatbook.js when we're rendering the, uh, like the data.


[User] Please transcribe this text

[Assistant] So we have like this test data here. Actually, like let's say we did want to eventually like fetch some data from the database. Uh, what we would have to do is.


[User] Please transcribe this text

[Assistant] Assuming that, uh, like this, like data that we're passing into chat, the chat component is a state. Then we can update the state with the data that we're fetching from the database and then they can all like propagate downwards. So.


[User] Please transcribe this text

[Assistant] Active chat should be in the same format as the test data that we made in step one.


[User] Please transcribe this text

[Assistant] So in particular it has a recipient and also like an array of messages.


[User] Please transcribe this text

[Assistant] At the top of the component, we still have like the, the dummy data that we defined earlier and, um,


[User] Please transcribe this text

[Assistant] We just want to make sure the page looks exactly the same way that it did before, but, but that active chat is now like a state.


[User] Please transcribe this text

[Assistant] I'll give you guys like three minutes to try this on your own and then we'll come back together in live code.


[User] Please transcribe this text

[Assistant] Okay. So does anyone need more time to, uh, implement this step?


[User] Please transcribe this text

[Assistant] So remember that inside of the useState hook is where we initialize like the value that we want. So, uh,


[User] Please transcribe this text

[Assistant] We want the default recipient to be all chat and we want the default list of messages to be test messages. And


[User] Please transcribe this text

[Assistant] Uh, this, you'll notice that this object is essentially the same, uh,


[User] Please transcribe this text

[Assistant] That we just, the same like object that we were using for our test data before, we're just initializing it to be like the same thing.


[User] Please transcribe this text

[Assistant] Uhm, and then for the data that we're passing into the chat component, we'll just pass in this like active chat.


[User] Please transcribe this text

[Assistant] It's just now that, now the data that's being passed into the alt chat is like a state, so it's dynamic.


[User] Please transcribe this text

[Assistant] To make sure we're all on the same page, you can run git reset dash dash hard, git checkout, workshop eight, step three.


[User] Please transcribe this text

[Assistant] Now we want to implement the API endpoints to actually start receiving messages and also like.


[User] Please transcribe this text

[Assistant] Basically we'll start by adding a message schema that defines like what the structure of a message looks like in the database. And then we'll add like, uh,


[User] Please transcribe this text

[Assistant] Like I just mentioned, a post request to post a message when a user actually presses the submit button. And it also get requests to get all the existing messages.


[User] Please transcribe this text

[Assistant] Uh, well actually I guess we'll just slide with this.


[User] Please transcribe this text

[Assistant] So I guess we'll start in message.js for step 3.1.


[User] Please transcribe this text

[Assistant] So the first thing that we want to store is like a sender object. And remember that


[User] Please transcribe this text

[Assistant] Uh, the sender of the message is just a user, so we also want them to have like, our prescribed ID, which is just a string. And also a name.


[User] Please transcribe this text

[Assistant] Which is also like a user object. So this will have a string and a name or an underscribed D, which is a string and a name, which is also a string.


[User] Please transcribe this text

[Assistant] And then finally, another like piece of information that we can store if we want to eventually render it is like a timestamp. Like maybe we care about when these messages are actually sent. So.


[User] Please transcribe this text

[Assistant] The way that we can initialize, like, a timestamp in Mongo is using, like, uh, the type, the type is, like, date. And, uhm, we can give it a default of date.now.


[User] Please transcribe this text

[Assistant] So essentially what this does, it allows us to like, whenever we're creating a new message object, we don't actually have to declare a timestamp.


[User] Please transcribe this text

[Assistant] So this basically becomes like optional because when it's passed into the database, like the default value will just be initialized as like date dot now. So we don't have to worry about like creating a timestamp every time we create a new message and then.


[User] Please transcribe this text

[Assistant] Um, the next thing that we want to do is we want to add a post request to post the message. Uh, essentially this post request will be called every time the user presses the submit button. So we can implement this in API.js.


[User] Please transcribe this text

[Assistant] So step 3.2, we want to implement the post request message route. So the syntax for post request is router.post message and


[User] Please transcribe this text

[Assistant] In order to be able to send a message, we want to make sure that they're logged in so we can pass in this middleware called like ensure logged in. This is, this function is defined in the auth.js file. If you want to take a look later. Um.


[User] Please transcribe this text

[Assistant] You can always make a post request like without accessing the UI just by like typing, uh, like a URL in the, uh, or like typing a URL in like the,


[User] Please transcribe this text

[Assistant] Uh, the URL of the post request. So like, for example, I type in into my browser, like localhost 3000, uh,


[User] Please transcribe this text

[Assistant] Even though you have the ability to do this, you have to make sure that you're actually logged in.


[User] Please transcribe this text

[Assistant] Um, but anyways, to continue with like this implementation, the first thing we can do is just like console log just for debugging, like.


[User] Please transcribe this text

[Assistant] So remember we talked about like earlier today, like this idea of like this rec.user object, because we're ensuring that we're actually logged in, we know that this rec.user object exists, and then, uhm,


[User] Please transcribe this text

[Assistant] We know like all the, we already defined that like a user object has a name. And then finally like RectapBody just accesses like the body of the post request, which we'll like construct later. But essentially we're saying that when we do make these post requests, we'll pass in like a key called like content. And then this will like display here.


[User] Please transcribe this text

[Assistant] This message object is just the same one that we just created, uh, like the, the same like schema that we just created. So we want a recipient.


[User] Please transcribe this text

[Assistant] So the person who is sending this message is the one who's like making the post request.


[User] Please transcribe this text

[Assistant] So the ID and name can be accessed with direct dot user object.


[User] Please transcribe this text

[Assistant] Even though we're creating a new message object here, we do not have to declare a timestamp because we said that the timestamp has like a default value. So when we make this new message object, it will be like


[User] Please transcribe this text

[Assistant] Uh, implicitly like initialize to whatever like date.now is. So we don't have to like explicitly declare it.


[User] Please transcribe this text

[Assistant] And the last thing that we have to do for this step is to implement another endpoint, which is to fetch all the chat messages when you initially load the page. So this is just going to be a get request, uh, slash chat and then.


[User] Please transcribe this text

[Assistant] We want to look for all messages that correspond to some recipient. So.


[User] Please transcribe this text

[Assistant] We can search for the recipient by their name or their underscore ID. For now, we're going to hard code like, uh, all chat as our recipient.


[User] Please transcribe this text

[Assistant] Eventually when we want to support like DMing other people, we'll pass in the recipient as like,


[User] Please transcribe this text

[Assistant] Uh, like into like the get request, um, and then we'll be able to like fetch all the messages for a specific recipient. Uh, but for the purpose of this workshop, we're just going to stay with like, assuming that we're always messaging like the global alt chat.


[User] Please transcribe this text

[Assistant] So does anyone have any questions about these two endpoints?


[User] Please transcribe this text

[Assistant] Check out workshop 8 step 4. And, uh, this will have all the code that we just wrote. So what we want to do in step 4 is...


[User] Please transcribe this text

[Assistant] Now that we've actually set up our backend, now we want to link together our


[User] Please transcribe this text

[Assistant] Both our front end and our back end. And we'll start by doing this with the send message function.


[User] Please transcribe this text

[Assistant] So if you'll, you'll remember that in new postinput.js,


[User] Please transcribe this text

[Assistant] In the very first step of the workshop, we set up this send function, uh, like callback function that was called every time we pressed the submit button.


[User] Please transcribe this text

[Assistant] And what we did was we just console logged the value, but now we want to actually make a post request to the endpoint that we just set up, slash API slash message. And


[User] Please transcribe this text

[Assistant] What this will do is it will save the message into the database so that the data actually persists instead of like going away every time we refresh the page.


[User] Please transcribe this text

[Assistant] Help you out, but we'll maybe give you, I'll maybe give you like two or three minutes to try this for yourself and then we'll come back together in live code.


[User] Please transcribe this text

[Assistant] Okay, so does anyone need more time to implement this?


[User] Please transcribe this text

[Assistant] Alright, cool. So, there's not actually that much code here. We just, uh, want to directly make the POST request. So, slash API slash message.


[User] Please transcribe this text

[Assistant] Again, recipient is coming from, it's defined here, it's like our, our props. So we can just directly access this with props.recipient. And the content is passed into us, into this like function, uh, which is just like the value. And that is basically it.


[User] Please transcribe this text

[Assistant] So if this works, we should be able to go to our catbook now.


[User] Please transcribe this text

[Assistant] And remember that inside of the post request we like constant logs the recipient and also the.


[User] Please transcribe this text

[Assistant] Like the content, the message in the server. So we should be able to see like if I send a new message.


[User] Please transcribe this text

[Assistant] Oh yeah, so just to make sure we're all on the same page, hit reset hard and check out workshop eight, step five.


[User] Please transcribe this text

[Assistant] And we're almost done. The last thing that we want to do is you'll notice that when I'm loading my page.


[User] Please transcribe this text

[Assistant] So we just implemented sending messages to the database, but when I reload the front end, you'll notice that the message like doesn't show up.


[User] Please transcribe this text

[Assistant] And that's because we're not actually fetching the messages from the database right now.


[User] Please transcribe this text

[Assistant] Uh, fetch all the messages every time we reload the page.


[User] Please transcribe this text

[Assistant] So I guess we'll just implement this together. So if you go to chaplook.js.


[User] Please transcribe this text

[Assistant] We have this like loadMessageHistory function.


[User] Please transcribe this text

[Assistant] Uhm, so inside of loadMessageHistory, we, uhm, essentially what we want to accomplish with this function is, uh, exactly like kind of what it like sounds like is we want to load all the messages. So.


[User] Please transcribe this text

[Assistant] The first thing we'll do is we'll make a get request to the endpoint that we defined earlier slash API slash chat.


[User] Please transcribe this text

[Assistant] Inside the, like the body of this get request, we'll pass in the recipient ID that.


[User] Please transcribe this text

[Assistant] Uh, we want to get for so again, like for now, this, uh, recipient idea is not really relevant because we're only sending messages to like all all chat, but eventually.


[User] Please transcribe this text

[Assistant] Uhm, we want to pass in different recipient IDs when we're like DMing like individual users. So this is why we're doing this like this. And then.


[User] Please transcribe this text

[Assistant] Remember that this get, this like get request for all the messages returns like just an object or like an array of message objects. So what we can do is.


[User] Please transcribe this text

[Assistant] Which takes in a recipient, uh, which is an input to this function and also, uh, the array of message objects.


[User] Please transcribe this text

[Assistant] And finally, what we want to do is we want to call this function every time that the page loads. So we already kind of have this set up here, but, um,


[User] Please transcribe this text

[Assistant] Inside this use effect, notice that this use effect has an empty dependency array, which means that it will, all the code inside will run, uh, every time the component mounts. So for example, if you refresh the page, this code will run. And we just want to call this load message history function.


[User] Please transcribe this text

[Assistant] Remember that all chat is just a user object that we had previously defined up here.


[User] Please transcribe this text

[Assistant] So all chat is like hardcoded. Eventually we can support.


[User] Please transcribe this text

[Assistant] Uh, different like, fetching requests for, or fetching the messages for like different users as well.


[User] Please transcribe this text

[Assistant] Hopefully everyone had a chance to like copy this down. Uhm, but if we go to the chat book now and we log in.


[User] Please transcribe this text

[Assistant] We'll see that the messages are loading and also if we send like a new message.


[User] Please transcribe this text

[Assistant] So if you want to see like the final products, uh, you can reset hard and check out workshop eight complete. And that is pretty much everything for this workshop.


[User] Please transcribe this text

[Assistant] Alright, so I guess we can just dive into it. Uhm, I'm going to start off today kind of reviewing a few of the steps that we covered yesterday because I know that it was pretty fast. I just want to make sure that everyone was on the same page. So just to get everyone oriented.


[User] Please transcribe this text

[Assistant] Uh, essentially what we'll be building out today, again, is like this live chat feature where you don't have to refresh the page in order to see DMs. And...


[User] Please transcribe this text

[Assistant] And today we'll be building out some other features like this chat list and the single user.


[User] Please transcribe this text

[Assistant] Again, just to like kind of navigate through where all these things lie on the page. This chat feature is this right half that we built out in workshop eight. And in order to allow DMs, we're going to be building out this chat list, uh, that's composed of like individual single user objects.


[User] Please transcribe this text

[Assistant] In workshop eight, we also built out a few API endpoints, specifically the get endpoint at slash chat, which clients can use to obtain new messages to display on the server or on their clients.


[User] Please transcribe this text

[Assistant] Uhm, and a post message, uh, endpoint where clients can send you messages to the server, uh, where it will be saved in the database and other clients will be able to retrieve it.


[User] Please transcribe this text

[Assistant] Alright, so just to kind of review like what we walked through yesterday, uhm, could everyone follow these steps to get started with Workshop 9?


[User] Please transcribe this text

[Assistant] I'll actually do the same thing in my terminal as well, so git fetch.


[User] Please transcribe this text

[Assistant] Hit reset hard. Hit checkout. That'd be nine slash or dash starter. Uh, don't forget to pull because we did make some changes.


[User] Please transcribe this text

[Assistant] I guess when everyone's like at the step with me, could I just get a quick thumbs up? Sweet. Okay, so.


[User] Please transcribe this text

[Assistant] So if you'll recall from the lecture yesterday, we kind of have a two-step process for the basic utilization of a socket. And the first step in that process is to broadcast a message from the server to all the connected sockets.


[User] Please transcribe this text

[Assistant] And in order to emit a message to everyone connected to the server, we're going to use this following syntax. So we're going to say socket manager dot get IO, which will get all connected sockets. And then we're going to use dot emit to emit an event.


[User] Please transcribe this text

[Assistant] And again, we'll specify the event name that we're listening for. And these should be the same thing, uhm, just to make sure that like, we're listening for the correct event.


[User] Please transcribe this text

[Assistant] And again, we said this was a two step process, so we're first going to start with broadcasting this message on the back end. So if everyone could navigate to app.js. Alright, sorry, api.js.


[User] Please transcribe this text

[Assistant] And navigate to the slash message endpoint that we implemented in workshop eight. This should be line 85.


[User] Please transcribe this text

[Assistant] We can see that like this is where we receive a message from the client, uh, kind of create a message database object and then save it to the database.


[User] Please transcribe this text

[Assistant] And again, as I mentioned, we'll be using this syntax displayed on the board, uh, with this getIo and emit. So this will be socket manager.getIo.emits.


[User] Please transcribe this text

[Assistant] And again, we get to kind of name this event anything we want, uh, because it's representing a new message. We're just going to call this message for now.


[User] Please transcribe this text

[Assistant] And finally, we're going to pass some data along with this event to the client. And this will be the message object that we just created.


[User] Please transcribe this text

[Assistant] The next step is to again, have the client listen for this message. So in order to do this, we can navigate to catbook.js.


[User] Please transcribe this text

[Assistant] And then we'll need to specify what we want to do with the data that's passed alongside that socket, uh, emission. And we've actually, again, already implemented this, this function up here for you called AppMessages.


[User] Please transcribe this text

[Assistant] What this does is it simply takes the new message, uh, in this case we call it data.


[User] Please transcribe this text

[Assistant] And now the client knows that it should use this function whenever it hears this message event.


[User] Please transcribe this text

[Assistant] So finally, uh, again, we have to add this cleanup function whenever you use sockets. And again, I'll, I'll just take this out real quick and explain what's happening in a bit. So it'll look like this.


[User] Please transcribe this text

[Assistant] socket.off, and we'll pass in the same parameters we used for the socket.on.


[User] Please transcribe this text

[Assistant] So remember that whenever we have a use effect, we can perform what's called a cleanup by returning a function in the return statement.


[User] Please transcribe this text

[Assistant] And what this will do is it will execute the code in the function whenever the component that it's contained in dismounts. So in this example, whenever this chatbook page dismounts, for example, this could be navigating away from the page or closing the browser.


[User] Please transcribe this text

[Assistant] The server will be able to use that socket to immediately notify all clients that a new message has been received, as well as pass that new message along to them for them to display on their browsers.


[User] Please transcribe this text

[Assistant] And just to like, be sure we can demo this, so if we navigate to, let me start my server.


[User] Please transcribe this text

[Assistant] And then if we navigate to our localhost 5050, login.


[User] Please transcribe this text

[Assistant] And also again, this should work with multiple users. So if you open up another Google account, uhm, and log in.


[User] Please transcribe this text

[Assistant] I should be able to send a message from this account and see it on the other without typing anything. Or refreshing a page, sorry.


[User] Please transcribe this text

[Assistant] Cool, so is everyone able to see new messages without refreshing the page?


[User] Please transcribe this text

[Assistant] Can I just get like a thumbs up if we're all good? Nice. Okay.


[User] Please transcribe this text

[Assistant] And what that endpoint is going to do is it's going to allow the client to say, hey, I'm like whiskers, for example, and this is the socket that I'm connected to.


[User] Please transcribe this text

[Assistant] Step one. So in order to get caught up, uh, could everyone get reset dash dash hard?


[User] Please transcribe this text

[Assistant] So the first thing we're going to do is create this init socket endpoint that the client will be able to use in order to tell the server which socket they're connected to.


[User] Please transcribe this text

[Assistant] And as with all of our other API endpoints, we'll kind of implement this in API.js. So if we can all navigate to that file.


[User] Please transcribe this text

[Assistant] And then number 82, line 76, we see that there's kind of this, uhm, empty in socket endpoint that we need to fill out.


[User] Please transcribe this text

[Assistant] So what we're going to do is we're first going to check if the user's logged in, because if the user isn't logged in, there's not really any person that we can associate this socket with. So we're going to say if record.user


[User] Please transcribe this text

[Assistant] And what this will happen is like, if this field is not null, uh, this code will execute, otherwise nothing will happen.


[User] Please transcribe this text

[Assistant] And we're going to use that socket manager package that we've implemented for you, uhm, in order to kind of register this user and associate with its socket. So it's going to look like socket manager.


[User] Please transcribe this text

[Assistant] And the first argument will be simply the user that's calling this endpoint. So rec.user.


[User] Please transcribe this text

[Assistant] And we can get this with another function that we've provided for you. Uh, and that's at socket manager.


[User] Please transcribe this text

[Assistant] Yeah, so we'll get into that in a bit. Uhm, when we call this API endpoint, we'll need to pass in like this socket ID as part of the body of the request. So that'll be like in the next step. Yeah.


[User] Please transcribe this text

[Assistant] Yeah, so addUser is a function that we've written for you that essentially tells the server to remember that


[User] Please transcribe this text

[Assistant] If we don't do that, the server won't know that the user that's calling this endpoint like owns this socket. They'll just be like anonymous sockets.


[User] Please transcribe this text

[Assistant] Yeah, so if you recall, like when we make posts, uh, request, post requests to post endpoints,


[User] Please transcribe this text

[Assistant] We can pass in some data in the body of the request. And we'll see how we can do that in a bit when we actually call this function from the client.


[User] Please transcribe this text

[Assistant] Uhm, and just to kind of like answer the second part of your question, like this is essentially a function that we've written for you.


[User] Please transcribe this text

[Assistant] That takes like the socket ID we pass in and gets the socket.


[User] Please transcribe this text

[Assistant] That is associated with that socket ID so that we can kind of say that this socket belongs to this user.


[User] Please transcribe this text

[Assistant] Okay, so now that we've implemented this endpoint, the next step is to have the client call this endpoint so that we can register all of them, uhm, and know which sockets belong to who. To do that, we're going to navigate to app.js.


[User] Please transcribe this text

[Assistant] And you can see some code here that like, handles the login that we talked about yesterday.


[User] Please transcribe this text

[Assistant] And what we want to do is like after the user logs in, we'll want to call this in its socket endpoint and establish that like, okay, I'm logged in now.


[User] Please transcribe this text

[Assistant] I'm going to tell you that this socket belongs to me.


[User] Please transcribe this text

[Assistant] And here's where we can pass in like that, uh, information that belongs to the rec.body here. We'll pass in, uhm, an object with a field called socket ID.


[User] Please transcribe this text

[Assistant] And the value of that will be socket.id, where this is essentially like.


[User] Please transcribe this text

[Assistant] The ID that the socket or the client is using, uhm, it's essentially a random string that's generated whenever, uh, the client connects with the new socket.


[User] Please transcribe this text

[Assistant] They'll make this post request to this init site endpoint we've implemented.


[User] Please transcribe this text

[Assistant] Which will tell the server to remember that like this user is associated with this socket. And we'll see in the next few steps how we can actually use that to our advantage to implement DMs.


[User] Please transcribe this text

[Assistant] Okay, so our next step will just be to build out some of like the components that we'll be using to implement DIMs. Uhm, so if we could all like just get on the same page by...


[User] Please transcribe this text

[Assistant] Uh, and don't forget to get full on this step, uh, cause we made some changes to the ModelGrid server as well.


[User] Please transcribe this text

[Assistant] Okay, so our first step in this step will be to like implement the components that represent these individual, uh, names. We should be able to click on to change our chat. So this will be done in singleuser.js.


[User] Please transcribe this text

[Assistant] And you can see there's like some skeleton CSS here, which isn't the most important thing in the world, just some styling to make it look as shown on the slides. Uh, the key part here is like this onclick button. And what we want to happen when we click on one of these users,


[User] Please transcribe this text

[Assistant] And if we look at our code, we'll want to call this function when this component is clicked. So within this onclick, uh, callback function.


[User] Please transcribe this text

[Assistant] We'll want to access the callback function that we passed down from our chat look, uh, to our chat list and then to our single user. So this will be in props.setActiveUser.


[User] Please transcribe this text

[Assistant] And the user we want to set, uh, is the user that this single user represents. Yeah.


[User] Please transcribe this text

[Assistant] As I mentioned, like, when we click on this single user component, we'll want to set the active user to the user that this single user represents. And that can be found in this, like, user prot that we passed down.


[User] Please transcribe this text

[Assistant] And kind of as we build out like the parents of this component, you'll see kind of how all this information flows down.


[User] Please transcribe this text

[Assistant] One last thing is we'll also need to actually like display something for the user to see when they look at these buttons.


[User] Please transcribe this text

[Assistant] So that would just be like the name of the user that the single user represents.


[User] Please transcribe this text

[Assistant] Uhm, we're going to use like this common React syntax we've seen when we want to like populate an array of components. And it's going to look something like, uhm,


[User] Please transcribe this text

[Assistant] So remember that uhm, this dot map function takes like an array and applies like some callback function on every element in the array.


[User] Please transcribe this text

[Assistant] So we're going to essentially map all of these users to a single user component.


[User] Please transcribe this text

[Assistant] Which again, we're past, we're actually obtaining from like a prop itself as well.


[User] Please transcribe this text

[Assistant] So again, essentially what's happening here is we have a list of users that we want to display in this childless component. And we're going to use this dot map syntax to do that.


[User] Please transcribe this text

[Assistant] Uh, and we're going to map every single one of these user objects to a single user components. I actually forgot one thing here. Oh, yeah.


[User] Please transcribe this text

[Assistant] Kind of react specific thing where like if we are rendering multiple components of the same type.


[User] Please transcribe this text

[Assistant] On a single page, React expects them to have a unique identifier as the key.


[User] Please transcribe this text

[Assistant] So that's kind of like why we pass this index in to have to give each of these components a unique index. Uhm, it doesn't.


[User] Please transcribe this text

[Assistant] It's not strictly necessary to do this, but if you don't include this and you look at your console, you'll see that react gives you a bunch of warnings. It's essentially because like.


[User] Please transcribe this text

[Assistant] React uses this key to like optimize rendering. And when it's missing, it like doesn't like it.


[User] Please transcribe this text

[Assistant] So that was like essentially implementing those two components. The next step for us is to actually add the chat list component to our chat with page.


[User] Please transcribe this text

[Assistant] And again, uhm, just because we made some changes, we can pull here to make sure we're all up to date.


[User] Please transcribe this text

[Assistant] So this could be none in chatbook.js. And on line 86, you'll see where the change could be made.


[User] Please transcribe this text

[Assistant] Yes, there's right now a dummy set active user, uh, right, that we've...


[User] Please transcribe this text

[Assistant] We'll implement in the next few steps, but for now you can just kind of use this to pass in as that prop.


[User] Please transcribe this text

[Assistant] Alright, how are people feeling? Do you think we need more time or are we ready to go ahead and walk through this?


[User] Please transcribe this text

[Assistant] So what we want to do is again add this chat list component to our chatbook page. And to that we're going to add it to this div right here.


[User] Please transcribe this text

[Assistant] So first let's just add this chat lists tag to our JSX.


[User] Please transcribe this text

[Assistant] And all we will need to do is fill out the individual props that should be passed to this chat list component.


[User] Please transcribe this text

[Assistant] So if we look at kind of what props our chat list is expecting, we'll see that it expects four props.


[User] Please transcribe this text

[Assistant] The first one is the users to display, so we can go ahead and fill that out.


[User] Please transcribe this text

[Assistant] So remember that this active user state, uh, will eventually be populated. We'll do that in a future step, but it will represent all of the users that are connected to the website currently.


[User] Please transcribe this text

[Assistant] Which represents the current active user that you're chatting with.


[User] Please transcribe this text

[Assistant] And we can obtain this from the active chat state. The recipient of the active chat is who we're currently chatting with.


[User] Please transcribe this text

[Assistant] The next thing this chat list expects is the user ID of the client who's associated with this, uh, or the user that's associated with this client.


[User] Please transcribe this text

[Assistant] So this will be user ID and this is actually passed down to us from the app component.


[User] Please transcribe this text

[Assistant] And finally we'll pass in that set active user callback function we've been mentioning.


[User] Please transcribe this text

[Assistant] Which again, right now is just a dummy function, but we'll fill it out in the next few steps.


[User] Please transcribe this text

[Assistant] Okay, cool. So if you navigate to like our local host right now, and we go to the chat page.


[User] Please transcribe this text

[Assistant] You'll see that we don't actually see anyone here. And the reason for this is because we haven't actually populated, like, this active user state that represents everyone who is currently connected to the website. So that will be kind of the focus of our next step. And...


[User] Please transcribe this text

[Assistant] Just to get on the same page again, let's go to our terminal.


[User] Please transcribe this text

[Assistant] So in this step, we'll be building a new endpoint at slash API slash active users, which will tell the client all of the users who are currently connected to the websites.


[User] Please transcribe this text

[Assistant] And this can be done in API.js along with all of our other API endpoints at line 103.


[User] Please transcribe this text

[Assistant] So remember, to send something back to the user, we're going to use this res.send function.


[User] Please transcribe this text

[Assistant] And we're going to want to build an object that has a field called active users.


[User] Please transcribe this text

[Assistant] Remember that like this is supposed to return a list of all of the active users. And as the slides say, we can use this function that we've written for you again, as part of the socket manager package.


[User] Please transcribe this text

[Assistant] In step one and step two, or just step one, we implemented that init socket endpoint where the user would register its name with its socket. That's kind of how the server is able to tell who's still connected to the website.


[User] Please transcribe this text

[Assistant] Are there any questions on this part, or kind of like what we're trying to do, or what any of these functions are accomplishing?


[User] Please transcribe this text

[Assistant] So as with all of our API endpoints, once we write the endpoint in API.js, the next step is to actually call that API endpoint somewhere in our client.


[User] Please transcribe this text

[Assistant] So this will be step five. So if you could all get reset, dash, dash, hard.


[User] Please transcribe this text

[Assistant] And here what we'll do in this use effects is when the page loads, we'll want to call this endpoint to make sure, or to get a list of active users so that we can use it to populate our chat list here.


[User] Please transcribe this text

[Assistant] For, or like making API requests is asynchronous. So this is actually a promise that we'll want to use this dot then syntax for.


[User] Please transcribe this text

[Assistant] And once we, you know, get the data back from this endpoint, we want to populate this state that we have defined above called active users.


[User] Please transcribe this text

[Assistant] And if you remember, like, the object that's returned by this endpoint we've written, uhm,


[User] Please transcribe this text

[Assistant] So we'll want to access that field on the client side by setting data.active users.


[User] Please transcribe this text

[Assistant] There's this option for all chat that's not actually technically the user, but we always want to have the option to chat with all chat. So we're just going to hardcore that into our active use as well. So we'll say.


[User] Please transcribe this text

[Assistant] That not only do we want to have the RAV like the active users, we also


[User] Please transcribe this text

[Assistant] And we're going to concatenate all of the active users we just received from the server to that array as well.


[User] Please transcribe this text

[Assistant] And remember, we want to do this because this active user state is what allows the chat list to know what they should display in this list.


[User] Please transcribe this text

[Assistant] And then go to the chat page. We should see that we should be able to see our component here.


[User] Please transcribe this text

[Assistant] Now there's like an interesting, uhm, interaction here, which is that


[User] Please transcribe this text

[Assistant] If you look at the way we defined our population of the state, this only happens once upon page loading. And if you notice what happened here is like.


[User] Please transcribe this text

[Assistant] Uh, the reason for this is a bit subtle, but what's actually happening here is that the page load is occurring before the socket connection is established, so the server doesn't know that I'm connected yet.


[User] Please transcribe this text

[Assistant] If you like Navi to a different page and go back, you'll see that I now show up. Because the socket has already had time to establish.


[User] Please transcribe this text

[Assistant] So this kind of motivates like the next step of this workshop, but just to make sure everyone's on the same page, I just wanted to pause here for any questions.


[User] Please transcribe this text

[Assistant] Okay. Well, I guess I restart the server and break the socket connection. Let me just demo it real quick.


[User] Please transcribe this text

[Assistant] And then I reload this page and log in.


[User] Please transcribe this text

[Assistant] Okay, so in order to fix that, uhm, I guess like does anyone have any ideas of like how we could potentially fix that?


[User] Please transcribe this text

[Assistant] Using like a very similar solution, uhm, to our live chat.


[User] Please transcribe this text

[Assistant] Yeah, exactly. So what we can do is set up another socket event that notifies all the clients whenever like a new active user either joins or leaves the chat.


[User] Please transcribe this text

[Assistant] So that's what we're going to be doing in step six. So if we could all git reset, dash dash hard.


[User] Please transcribe this text

[Assistant] So all you have to do is make a change on the client side to listen for that event. So this event is called Active Users.


[User] Please transcribe this text

[Assistant] And update the active users list accordingly whenever we outcatch that event on the client.


[User] Please transcribe this text

[Assistant] Oh yes, so we're listening specifically for an event called, uhm, Active Users. Yeah, so like.


[User] Please transcribe this text

[Assistant] Instead of this, this message, you would see like active users because of, yeah, that's like the name of the...


[User] Please transcribe this text

[Assistant] And when we get a message or get that active users event, we're going to make a new API call to the active users to update the active users, um, stored in chatbook.js in this state up here.


[User] Please transcribe this text

[Assistant] Okay, so, like, wait is this on? Are you able to hear me in the back?


[User] Please transcribe this text

[Assistant] Uhm, so the question was like, is socket.on asynchronous?


[User] Please transcribe this text

[Assistant] I guess that's just like, not really, like immediately when you call socket.on, it will start.


[User] Please transcribe this text

[Assistant] Listening on the client for the specific event that you specify here.


[User] Please transcribe this text

[Assistant] However, like it's possible that the callback function you pass in has like some asynchronous elements.


[User] Please transcribe this text

[Assistant] Okay, so what we want to be doing again is adding a new socket listener on the client. And we can use a very similar like,


[User] Please transcribe this text

[Assistant] Structure as the message listener that we created before. So we usually go ahead and get started with like this very basic, uhm, structure.


[User] Please transcribe this text

[Assistant] The first is that we're going to be listening for a different event. So let's go ahead and specify a new event here. This event will be called Active Users.


[User] Please transcribe this text

[Assistant] So I'm going to call this new callback function update active users.


[User] Please transcribe this text

[Assistant] I'm really, there's an inconsistency here. But that's fine. This active user's, uhm,


[User] Please transcribe this text

[Assistant] Event also passes a list of all new active users, so we don't actually need to make any API calls here.


[User] Please transcribe this text

[Assistant] What we simply need to do is take the data that is passed to the client alongside this bucket event and update our active state list accordingly, kind of like what we did, uhm, up here.


[User] Please transcribe this text

[Assistant] So again, because active uses is a state, we're going to be using the set function.


[User] Please transcribe this text

[Assistant] And similarly to above, like we always want all chat to be displayed. So we're going to manually hard code that in first.


[User] Please transcribe this text

[Assistant] And then we're going to concatenate all of the users that are currently connected, which we got from, um, like the software event.


[User] Please transcribe this text

[Assistant] This would turn off every socket that's listening to this though. So just to like, avoid any like...


[User] Please transcribe this text

[Assistant] You know, interleaving of like what we're trying to do, it's just easier.


[User] Please transcribe this text

[Assistant] More accepted practice to also pass in the callback function of like the one we're trying to turn off.


[User] Please transcribe this text

[Assistant] So again, what this is doing is this will say, I'm going to start listening for an event called Active Users.


[User] Please transcribe this text

[Assistant] Whenever I hear that event, I'm going to call this callback function, update active users.


[User] Please transcribe this text

[Assistant] What the Active Users function is going to do is it's going to take all of the active users and add it to a list.


[User] Please transcribe this text

[Assistant] With all chat in the beginning and set that to be the active users.


[User] Please transcribe this text

[Assistant] Here is passed into our chat list component. Uh, you'll see here. Allowing it to be rendered on the page.


[User] Please transcribe this text

[Assistant] So if we now navigate to our localhosts5015.


[User] Please transcribe this text

[Assistant] We'll see that, like, we don't have that air we had before where we didn't show up initially.


[User] Please transcribe this text

[Assistant] Furthermore, like if another user logs in, so if you open up a new tab and log in with a different account.


[User] Please transcribe this text

[Assistant] We should be able to see like this active user lists update automatically without us having to refresh the page.


[User] Please transcribe this text

[Assistant] And similarly when I log out, like it should automatically remove that user from the chat lists.


[User] Please transcribe this text

[Assistant] The answer is yes, but like, just to make it more readable, it's nice to have like, the different user effects separated out for, uh, different versions.


[User] Please transcribe this text

[Assistant] Gotcha. So that would definitely, are you saying like, could we turn, like turn on the socket in this use effect?


[User] Please transcribe this text

[Assistant] It's just, like, nice to have, like, a effect dedicated for, like, a socket. Yeah.


[User] Please transcribe this text

[Assistant] Yeah, sorry, that was, that was my bad. There was like some slight confusion on the slides, but like. If we. So we've actually defined uhm.


[User] Please transcribe this text

[Assistant] We know as the, like on the client side that we're going to be receiving all of the active users already.


[User] Please transcribe this text

[Assistant] So we can just like use that directly rather than like making a new API request that would essentially give us the same information.


[User] Please transcribe this text

[Assistant] Uhm, let me just see if I can find that real quick to make it.


[User] Please transcribe this text

[Assistant] Ah yes, so if you look here, like in serverstock.js, it's not like super important to understand everything that's happening here, but like this admission that we've defined for you.


[User] Please transcribe this text

[Assistant] It emits the active users event and we can see that like with it, it passes this data called active users, which is already like all the connected users.


[User] Please transcribe this text

[Assistant] Alternatively, like we could make any request every time we got that, like making a request to, uh, slash API slash get active users. Every time you heard that soft event, it would just kind of like be redundant because we already have that data.


[User] Please transcribe this text

[Assistant] Cool. But I guess is everyone able to like see the live updating, uhm, users in the chat?


[User] Please transcribe this text

[Assistant] So if you'll notice, like, when we, like, click on these buttons, nothing actually happens. And that's because, like, if you'll recall, we're actually just using a dummy function that does a console log every time we click one of them. So we'll see that, like, uhm, okay, hold on. Like, this console log occurs, but nothing else happens.


[User] Please transcribe this text

[Assistant] And we want to actually happen is like to change the chat that's displayed here. So that's what we're going to be doing in the next step.


[User] Please transcribe this text

[Assistant] And I think we'll actually just like walk through this one together because we're getting a little bit short on time. Um, but if there's any confusion, like feel free to stop me.


[User] Please transcribe this text

[Assistant] So what we're going to be doing is updating the setActiveUser function in chatbot.js, line 96.


[User] Please transcribe this text

[Assistant] And instead of a console log, we're actually going to want to change what's displayed in the chat. I guess I won't be able to see it right now because there's errors, but let's just fill that out. So the first thing I want to check is if I'm clicking on the user that's already active.


[User] Please transcribe this text

[Assistant] I don't actually want to do anything because like that user is already active, so we don't need to set it to be active.


[User] Please transcribe this text

[Assistant] If the user that's like, wants to be set active is already active.


[User] Please transcribe this text

[Assistant] I'm just going to like return here and the rest of the function will not be executed.


[User] Please transcribe this text

[Assistant] And I'm going to use the set active chat setter because again, active chat is a state.


[User] Please transcribe this text

[Assistant] And remember that like the active chat is like this object with messages and recipients.


[User] Please transcribe this text

[Assistant] And the messages we can kind of just initialize to be an empty array because we're going to do right after this.


[User] Please transcribe this text

[Assistant] Is we're going to call load of message history, which will.


[User] Please transcribe this text

[Assistant] Which will, uhm, kind of obtain all of the messages for the user that we care about.


[User] Please transcribe this text

[Assistant] And you can see that that function is actually defined, uh, up above. So if we look at.


[User] Please transcribe this text

[Assistant] It simply makes an API call to the slash chat endpoint, uh, with the new recipient and it will set the chat messages accordingly.


[User] Please transcribe this text

[Assistant] Just to kind of like walk through of another way you'd structure this, one possible way we could do this is instead of like having this load message history here, we could instead add


[User] Please transcribe this text

[Assistant] The ActiveChat recipient as a dependency of this, this use effect here. So just kind of like walking what that would look like.


[User] Please transcribe this text

[Assistant] And instead of loading like all chat every time, we would want to load the chat of the current active user.


[User] Please transcribe this text

[Assistant] Anytime the recipient of the active chat changes, I'm going to call this function that will load the correct messages accordingly.


[User] Please transcribe this text

[Assistant] Like both of those ways would be valid. Uhm, it's kind of just like a matter of preference.


[User] Please transcribe this text

[Assistant] You'll actually still see that when we click on, uh, different users, the chats can change. And that's because like this endpoint we set up.


[User] Please transcribe this text

[Assistant] Uh, this slash API slash chat endpoint is not yet set up to actually return messages that are not all chat. And we can see that if we like navigate to API.js.


[User] Please transcribe this text

[Assistant] We'll see that at slash chat. We always query for all chat.


[User] Please transcribe this text

[Assistant] So, I guess does anyone have any questions about that so far?


[User] Please transcribe this text

[Assistant] Okay, cool. So our next step would be to update this slash chat endpoint, and we'll do that in step eight.


[User] Please transcribe this text

[Assistant] What we want to do here is update this database query so that instead of returning messages for all chat every time we call it,


[User] Please transcribe this text

[Assistant] Uh, this is like a kind of coding heavy part, so don't worry if you can't like follow along, uhm, live. It's okay, just watch for the step.


[User] Please transcribe this text

[Assistant] And we can like post more information about like what's exactly happening here. But essentially what we want to do is like first check to see if we're chatting with all chat.


[User] Please transcribe this text

[Assistant] And if we are chatting with All Chat, we're going to want to keep it through the same.


[User] Please transcribe this text

[Assistant] And I'm actually going to, uh, just define the query outside of this function as well.


[User] Please transcribe this text

[Assistant] And you'll see why in a bit, but essentially like we're going to want to conditionally set this query variable, uh, depending on whether this is an alt chat or a DM.


[User] Please transcribe this text

[Assistant] Then this is a DM, and we're going to want to look for messages that are sent from the user to the recipient or from the recipient to the user. Kind of like that two-way communication.


[User] Please transcribe this text

[Assistant] And we can do this by using this special syntax for database querying. It looks something like this.


[User] Please transcribe this text

[Assistant] I'm gonna look for messages whose sender is me and the recipient is the recipient, so the person I'm chatting with.


[User] Please transcribe this text

[Assistant] The other type of message you want to show is when it's reversed.


[User] Please transcribe this text

[Assistant] When the sender is the person I'm chatting with, so this req.query. And again, don't worry if you're like not able to follow this live, uhm, we'll like post these, these code solutions online.


[User] Please transcribe this text

[Assistant] The second type of message you want to listen to is the opposite when the person I'm chatting with is the sender, and I'm the recipient. And what the syntax does is it says,


[User] Please transcribe this text

[Assistant] I'm going to search my database and return queries that match this first query or the second query.


[User] Please transcribe this text

[Assistant] Uhm, I'm gonna simply find it the same way, find all the messages the same way I did before and then send those messages back to the client.


[User] Please transcribe this text

[Assistant] We'll see that we can, uhm, like correctly show or display the new chat. And if I like open up a new tab and start chatting with someone in a DM.


[User] Please transcribe this text

[Assistant] It should show up live on the other person's screen and when I navigate away, it should go back to all chat. And when I navigate, that's awkward.


[User] Please transcribe this text

[Assistant] Gotcha. So this, this field is just incorrectly named here.


[User] Please transcribe this text

[Assistant] Okay, so hopefully this works. So if we, again, go back to our different tabs, log in.


[User] Please transcribe this text

[Assistant] Okay, so let's say I'm like signing again. Yeah, I'm number two.


[User] Please transcribe this text

[Assistant] It shows up and it will persist that DM when I navigate back to the chat.


[User] Please transcribe this text

[Assistant] Like essentially this is almost everything we need and I am running out of time, but I just wanted to demo one more thing and I'll record a few of the last steps to view later.


[User] Please transcribe this text

[Assistant] But one interesting thing to think about is like, let's say that one of the users is in all chats, but like another user is sending a DM to someone else.


[User] Please transcribe this text

[Assistant] If you'll see that DM shows up in the alt chat and like, does anyone have an idea of why that might be?


[User] Please transcribe this text

[Assistant] So again, I have one user that's sending a DM and I have another user that's in all chats. And when they send a DM.


[User] Please transcribe this text

[Assistant] Yes, exactly. So, because our socket that we set up is just listening for any generic message events, any message that's sent, even if it's DM, will be caught and displayed on the browser.


[User] Please transcribe this text

[Assistant] In the next few steps that I'll like report and post online, I'll show like how exactly to fix this, but I encourage everyone to think about it themselves. And I would also like think about whether that change should be made on the client side or on the server side.


[User] Please transcribe this text

[Assistant] Like, the chat message is changing when we change tabs, and...


[User] Please transcribe this text

[Assistant] Uh, having them persist over time. I guess if you're able to copy the query.


[User] Please transcribe this text

[Assistant] If not, also feel free to like check out step nine. That should also, uh, work with the same behavior.


[User] Please transcribe this text

[Assistant] database query, sockets, how we may potentially fix this issue.


[User] Please transcribe this text

[Assistant] Okay, cool. So I guess that's it for now. If you have any questions, as always, like just feel free to either ask more questions doc or come up to us. Um, I'll post a video recording of the last few steps that show how to fix this issue by actually emitting events to individual sockets rather than everything. Um, and yeah, thanks for listening.


[User] Please transcribe this text

[Assistant] Alright, so welcome back everyone. Uhm, I'm just going to finish walking through the steps of workshop 9 that we didn't actually get to finish in class today.


[User] Please transcribe this text

[Assistant] And these steps kind of involve emitting socket events to individual sockets rather than everyone at once. And then just doing some filtering to clean up the chat at the end.


[User] Please transcribe this text

[Assistant] So we left Loving Glass by kind of looking at this one interesting issue, which is that if I'm logged in to... Okay, so I also need to start my site.


[User] Please transcribe this text

[Assistant] But if I'm logged into the, you know, multiple different accounts that are DMing,


[User] Please transcribe this text

[Assistant] Users who aren't part of that DM chain will still be able to see messages in all chat. And I'll demo that right now.


[User] Please transcribe this text

[Assistant] And just to make sure everyone's on the same page, uh, we can all get reset, dash dash hard.


[User] Please transcribe this text

[Assistant] And then again, that's npm run start to start the backend server and npm run hot loader to kind of run the local client server.


[User] Please transcribe this text

[Assistant] So let's take a look at this issue. I have three Google accounts logged into the website right now. And from left to right, these are Seymour, MI, and Michael.


[User] Please transcribe this text

[Assistant] And let's say that Seymour is trying to send a DM to MI.


[User] Please transcribe this text

[Assistant] As we can see, uh, MI is able to instantly see that DM as expected.


[User] Please transcribe this text

[Assistant] However, a third party, in this case Michael, is actually able to see that same message in all chat. Which is like clearly not what we want, right? Because DM should be private and shouldn't be accessible by users who aren't intended recipients. Just kind of demo that again if Michael responds.


[User] Please transcribe this text

[Assistant] Again, I'll see that DM in All Chat, even though I'm not, uh, this account, Michael, should not be able to see those messages.


[User] Please transcribe this text

[Assistant] And we discussed in class that the reason why this is happening is because our server in API.js on line 114


[User] Please transcribe this text

[Assistant] Is emitting this message event to every single connected socket, regardless of whether this is, uhm, a message meant for all chat or if it's meant as a DM.


[User] Please transcribe this text

[Assistant] This means that when the user, uh, the client is listening for, uh, on this message channel, so listening for these message events,


[User] Please transcribe this text

[Assistant] Any messages, regardless of whether they are DMs or alt chat, will be caught and then displayed on the browser.


[User] Please transcribe this text

[Assistant] As kind of we alluded to before, the way we're going to fix this is by...