Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Build Hangman with React and RxJS using react-streams


    Hangman presents an interesting problem where you have to process a word one letter at a time based on user input. This lesson shows how to use react-streams to solve that problem by creating a stream from the document keydown event and checking it against a stream of the word you're trying to solve.



    Become a Member to view code

    You must be a Pro Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    orLog In




    Instructor: First, I'll import from RxJS fromEvent. Then I use fromEvent to create a stream from the document keydown event. I'll call this keydown. Since I only want the key property, I'm going to pipe this through the map operator.

    Let's import that from RxJS operators, and import map. I'll write a function, and I want to grab the key property off of that. I'm just going to map this to an object where letter is assigned to key. The key property on the event is being passed through and assigned to an object with a letter on it.

    That's just to avoid the confusion around key, React keys, and so on. With this stream, I can display it in React. I'm going to import from React streams, and import the stream component. Now, my app will be a stream component, where the source is the keydown stream.

    Now, the stream component has a function as a child. I'm going to take that letter. I'll just display for now that letter. When I type a key, I'll type the letter A. You can see A showed up. Let's make this a bit bigger.

    I'll type BCDEF, or I'll just mash on the keyboard. You can see those document keydowns grabbing the key, coming through as the letter, and then that function rendering out that letter. Now, I'll create a second stream which I'll call word.

    I'm just going to say from the string, I'll use the word friendly as our word to figure out. I need to import from up here. I'm going to create a third stream, and just call it hangman. This is going to be the keydown stream.

    Anytime I press a keydown, I'm going to pipe it through. We'll use mergeMap. Let's import mergeMap. mergeMap will take a function. I'll destructure letter off of that. Then this will switch over to our word stream.

    Now, word is going to pipe through each letter at a time, because when you pass in a string, it's going to pass through F, then R, then I, then E. That's exactly how we want to process the word. We can just pipe that through and map it.

    Map takes a function. We'll call the letter that comes through, I'll just call that check. I'll say if check equals letter, then return the check. Return check or letter, it doesn't really matter there. If not, then return an asterisk to mask it.

    Then since that's processing the letters one at a time, we need to build the string back together. We'll scan and import scan. We'll just say the previous and next. We'll let this build up, so we have a previous and next.

    This string is just building one at a time. Then I'm going to map this to pass in a function, and our result will be in there. I'm just going to pass in an object that has a key and a property of result. Now, I can display my hangman stream.

    I'm going to wrap this stream, so wrap in a div, and put another stream underneath it, where the source is hangman. With the function as a child, we have the result that we want to display. I'll just display a result.

    When I type, if I type F, you can see the letter F. If I type R-I-E-N-D-L-Y, you can see that the letter that we type exposes the letter from the word. Let's put a horizontal rule there to separate that a bit better.

    I'll type F-R-I-E-N-D-L-Y. Whichever letter I type is the one that shows up. If I type one that's not in there, then that doesn't show up. Now, what we have to do is essentially accumulate all of our guesses. When we type a keydown, let's scan those.

    We'll start with an array. Let's import startWith. This array will push down into our scan, where we'll have the letters. This is an array of letters. Then the current letter, which comes through the keydown. Then the result, we want to be the previous letters spread out, and the new letter.

    Now, instead of one letter being passed into our mergeMap, and actually this is, as you can see here, a key on an object here. We need to destructure that there. Now, the mergeMap is going to take an array of letters, instead of just that single letter.

    I'll switch this over, and this letters needs to check here. Instead of checking of that letter is equal to the check, we can check if letters includes check. This is an array, and it's just seeing if that array has that letter.

    We'll hit save. Now, if I type F, you'll see F show up, R-I-E-N-D-L-Y. I'll refresh. I'm just going to mash on some keys here, and you can see that we're playing hangman.