Today I spent the day with my family (we talked a while, saw a movie and went out for dinner), but in between I also fixed up the GitHub authentication flow in my mob coding app and started to implement async/await!
Real-time notes
7:31am: Up early, feeling still more sleep-deprived than yesterday since I was up until past 1am again and never did get to take a proper nap. But I woke up thinking about a couple things I forgot about for yesterday’s updates to the mob coding app! First thing: why not just use the WebSocket connection to send the GitHub access token to the clients? (Well, I don’t know if it’s a secure connection. And I probably won’t mess with that yet.) Second thing: I probably shouldn’t send the actual temporary code from GitHub if I don’t need to. Third thing: how did it work with that Gatekeeper thing? Maybe I should provide the homepage URL as the callback URL to GitHub and just have the server do the authentication when the client makes an AJAX request to it.
…
8:48am: My laptop ran out of juice, and then I lied in bed for a while and finally walked over to the coworking space, all the while talking about HTTP requests and accessing headers from client-side JavaScript with my partner-in-crime, but we were talking in circles because I didn’t know how to phrase my question, haha. But I confirmed my understanding is indeed correct now. Then we stopped by an early morning tech event here to say hi to a couple people and grab a couple bites of the free donuts. I’m back at my computer now, coffee in hand. Let’s take a look at that Gatekeeper thing again!
Yup, I should follow this workflow – it’s much simpler!
…
9:27am: Back after chatting with a coworking friend I hadn’t seen in a long time. Distracted by other people talking too. Just finished the last of my donut bites. OK, so new workflow, this time more similar to Gatekeepr:
Updated mob coding user authentication flow
-
Client connects to server, establishing a WebSocket connection, and checks if a temporary code exists as a URL parameter. If none exists, the client makes an AJAX call to the server’s
/github-client
route, and upon receiving the GitHub client ID, the client displays the GitHub login link using the client ID. (Later I’ll probably just use server-side rendering/templating to accomplish this step!) -
User clicks login link, gets redirected to GitHub, and accepts permissions to authorize the app.
-
GitHub redirects user to the homepage of my app with a temporary code as a URL parameter.
-
The client checks again for the temporary code; if it does exist (and now it should!), then the client makes another AJAX call, this time sending that temporary code to the server’s
/github-token
route. -
The server makes a POST request to GitHub to exchange that temporary code (along with the client ID and client secret) for an access token, passing that token back to the client – not in the URL parameters this time!
-
The client stores that access token as a local JavaScript variable, completes the login process, and uses the locally stored token for all API requests, just like before!
Phew, that’s much better! I don’t know why I came up with yesterday’s convoluted process or thought that was a good idea, haha. OK, let’s fix this up!
9:57am: It works! I kept getting distracted by background conversations. Also, I forgot how promises work again. Well, time for a quick break, and then I’ll look at some examples of promise chains and see if I remember how to structure this. (Or I could just use async/await now!)
10:19am: Took a break and talked to my dad for a minute. I’m thinking I’ll spend the day there today, actually! Then I can stop in Culver City tomorrow morning to go climbing on my way back downtown. It would also be nice to take a real nap there. And I miss them!
Anyway, I got the promise chain working. This looks better. I’ll make a commit and all that and then walk home I think.
…
Personal check-in, 12:00pm: At my family’s house now, eating a small lunch. At first when I arrived, I felt a wonderful sense of calm and comfort and familiarity, but after a moment I felt a spike of anxiety again. Coming here feels like running away, although I dodn’t even know what I’m running away from. I felt fine most of yesterday and today. I guess I do just have a very strong association between being here – or leaving from here – and experiencing anxiety attacks. Now I’m not sure what to do. It’s only been a few minutes, but I feel like an hour has passed because I’ve already experienced so many different strong emotions and overwhelming thoughts. I want to be able to just relax, do a little more work, and enjoy spending time with family today, and then go rock climbing tomorrow before my afternoon meeting to discuss Girl Develop It stuff with our other main organizer and then my meetup tomorrow night. Maybe all these feelings and emotions are just the result of sleep deprivation. I don’t know. Maybe it suddenly caught up to me that I’m too tired to make much progress towards my goals, or maybe I just feel overcome with uncertainty again. Just when I was starting to feel surprisingly calm, anxiety took over again. I wish I could predict it better. Well, time to practice fighting it again.
…
2:39pm: I ended up talking to my dad and stepmom for a good while, catching up on what’s new and playing with the dogs. I did talk to them about how I was feeling for a while too, and their support means the world to me! It definitely helped, at least for a little while. Right now I just feel sleepy. Looks like we’re all going to go see a movie together and then go out for dinner, so I’m hoping that I’ll be able to relax enough to enjoy spending time with them today. In the meantime, I figured I’d do a little reading or coding. How about issue #7: use async/await instead of promise chains! I’ll try that out. It would be good to review that topic now, since I did mostly forget how it works again.
Reviewing my old notes, it’s funny to remember that “late night rabbit hole” when I first learned about async/await back on June 15th! Then I finally felt comfortable with them on June 19th after a great study session with my friend. That was also the day I finally figured out the difference between the two ways of handling errors in promise chains! Speaking of which, now that I jogged my memory, I should go fix that up in my code right now.
3:09pm: Distracted by TV, but I also replaced every var
with let
, because why not! I’ll end up using Babel or something to transpile my client-side JavaScript later on anyhow. OK, now for the async/await stuff… I’ll start with one small chunk:
Current code using promises:
get('/github-auth?code=' + tempCode).then(function(access_token){
currentAccessToken = access_token;
return getJSON('https://api.github.com/user?access_token=' + currentAccessToken);
}).then(loginUser).catch(handleError);
Same code rewritten with async/await:
async function asyncLoginUser (tempCode) {
try {
currentAccessToken = await get('/github-auth?code=' + tempCode);
let userData = await getJSON('https://api.github.com/user?access_token=' + currentAccessToken);
loginUser(userData);
} catch (err) {
handleError(err);
}
}
The code isn’t any shorter (it’s actually longer!), but it is more intuitive to read. I’ll try it out… Awesome, it works! On the first try! Woohoo! I guess I’ll also refactor the old loginUser()
to combine these two into one function. And then I’ll rewrite all the other promise chains similarly.
3:30pm: So far so good! I’m testing it after every change, and it’s working exactly as it did before. Woohoo! Time for a quick break.
3:56pm: Got stuck on refactoring the Gist forking/editing code… not sure which function should be an async function… So sleepy right now! Time to go see that movie. Hopefully I’ll stay awake.
…
9:03pm: I did stay awake, but now I feel a bit delirious. I also ate too much, so feeling full only makes me sleepier. But before I doze off on the couch here, I wanted to review async functions a bit more and maybe even finish what I started! Hmmm… oh OK, so async functions always return promises. And within an async function, using await
does block everything below, until the promise resolves. So I do need to wrap my entire function in an async function if I want code to be sequential and wait for results from previous calls across conditional statements. Not even sure if that makes sense in writing, but it makes sense in my head. Just hard to explain it right now. So sleepy! My computer is going to restart itself soon to do some updates, so I better test this out quickly…
9:23pm: Well, I didn’t finish it, but I made some notes to help me jump back in where I left off. I guess I’ll call it a night now.