1 00:00:06,718 --> 00:00:08,280 - In this section, we're going to start looking 2 00:00:08,280 --> 00:00:10,200 at the Reactive Extensions library 3 00:00:10,200 --> 00:00:12,600 for JavaScript, RxJs. 4 00:00:12,600 --> 00:00:14,880 Very useful if you are dealing 5 00:00:14,880 --> 00:00:17,040 with an Observable stream of data 6 00:00:17,040 --> 00:00:18,930 that's being pumped into your web application, 7 00:00:18,930 --> 00:00:22,050 maybe from a web socket on the server. 8 00:00:22,050 --> 00:00:24,570 At the heart of the Reactive Extensions library, 9 00:00:24,570 --> 00:00:26,670 there's a class called "Observable." 10 00:00:26,670 --> 00:00:30,120 And the basic idea is, it pumps values continuously 11 00:00:30,120 --> 00:00:32,430 into your code from elsewhere. 12 00:00:32,430 --> 00:00:34,260 And you can define a subscriber, 13 00:00:34,260 --> 00:00:37,650 which listens for that data and gets notified 14 00:00:37,650 --> 00:00:39,930 whenever a new piece of data arrives, okay? 15 00:00:39,930 --> 00:00:42,840 So what we'll have a look at then, in this section, 16 00:00:42,840 --> 00:00:46,860 a simple example of how to create an Observable stream 17 00:00:46,860 --> 00:00:50,010 that will be pumping data into my code, 18 00:00:50,010 --> 00:00:51,810 how to subscribe to that stream, 19 00:00:51,810 --> 00:00:54,600 to receive the values as they're emitted, 20 00:00:54,600 --> 00:00:56,640 and how to test that stream, to make sure 21 00:00:56,640 --> 00:01:00,000 that it emits the values that we expect it to emit. 22 00:01:00,000 --> 00:01:01,770 If you wanna follow along, 23 00:01:01,770 --> 00:01:05,403 the demos for this example are in that folder, TestingRxJs. 24 00:01:07,470 --> 00:01:09,360 Okay, so first things first, 25 00:01:09,360 --> 00:01:13,140 Reactive Extensions isn't a standard library in JavaScript. 26 00:01:13,140 --> 00:01:16,560 You have to download it in your package.json. 27 00:01:16,560 --> 00:01:18,870 So in the demo folder, 28 00:01:18,870 --> 00:01:22,050 I've got a dependency for the Reactive Extensions library. 29 00:01:22,050 --> 00:01:24,990 I've also got a dependency for babel/node. 30 00:01:24,990 --> 00:01:27,240 Babel/node is a tool that we'll use 31 00:01:27,240 --> 00:01:29,340 for running our JavaScript, okay, 32 00:01:29,340 --> 00:01:31,530 so that the code can execute, 33 00:01:31,530 --> 00:01:34,773 set up an Observable stream, and then subscribe to it. 34 00:01:35,640 --> 00:01:38,130 We'll run the test and the Jest obviously. 35 00:01:38,130 --> 00:01:40,380 So that's my package.json file. 36 00:01:40,380 --> 00:01:42,630 If you wanna follow along for yourself, 37 00:01:42,630 --> 00:01:45,510 go into the TestingRxJs folder, 38 00:01:45,510 --> 00:01:47,400 open that up in the code editor. 39 00:01:47,400 --> 00:01:50,280 In the code editor, you'll see... 40 00:01:50,280 --> 00:01:51,113 There we go. 41 00:01:51,113 --> 00:01:54,270 Those are my dependencies that I just specified. 42 00:01:54,270 --> 00:01:56,610 Okay? So that's the first step. 43 00:01:56,610 --> 00:01:59,370 Now the Observable class, like I said, 44 00:01:59,370 --> 00:02:02,850 Reactive Extensions is all about the Observable class. 45 00:02:02,850 --> 00:02:06,210 An Observable object represents a stream of data 46 00:02:06,210 --> 00:02:09,480 which is constantly going to be emitting values 47 00:02:09,480 --> 00:02:13,320 into your application, which you can subscribe and handle. 48 00:02:13,320 --> 00:02:15,270 So the first thing we're gonna do, 49 00:02:15,270 --> 00:02:17,190 we're gonna have to create an Observable object, 50 00:02:17,190 --> 00:02:20,940 which outputs or emits data. 51 00:02:20,940 --> 00:02:23,250 So there are lots of factory functions 52 00:02:23,250 --> 00:02:25,590 to help you to create an Observable. 53 00:02:25,590 --> 00:02:27,000 You can create an Observable 54 00:02:27,000 --> 00:02:29,130 that emits data in different ways. 55 00:02:29,130 --> 00:02:32,070 The simplest example, there's an of() function. 56 00:02:32,070 --> 00:02:36,600 Okay? So I've imported in this example, here, my code.js. 57 00:02:36,600 --> 00:02:38,790 I've imported the Reactive Extensions library 58 00:02:38,790 --> 00:02:39,804 for JavaScript. 59 00:02:39,804 --> 00:02:43,620 And then in that library, there's an of() function, 60 00:02:43,620 --> 00:02:47,070 and this function creates an Observable object. 61 00:02:47,070 --> 00:02:48,480 It's a factory function. 62 00:02:48,480 --> 00:02:50,730 It creates a new Observable object, 63 00:02:50,730 --> 00:02:53,520 which creates a new Observable object 64 00:02:53,520 --> 00:02:55,140 that emits a single value. 65 00:02:55,140 --> 00:02:56,520 Here, 42. 66 00:02:56,520 --> 00:02:59,430 Obviously that's my very simple function, 67 00:02:59,430 --> 00:03:02,040 which emits a single value. 68 00:03:02,040 --> 00:03:04,943 Okay. So if you wanna follow along, code.js, okay? 69 00:03:04,943 --> 00:03:08,220 There's my function, which creates an Observable, 70 00:03:08,220 --> 00:03:09,933 which emits a single value. 71 00:03:10,830 --> 00:03:12,540 So when you call that function, 72 00:03:12,540 --> 00:03:14,730 you will get back an Observable object 73 00:03:14,730 --> 00:03:16,713 which will emit a single value. 74 00:03:18,120 --> 00:03:18,953 Okay? 75 00:03:18,953 --> 00:03:20,340 So what we're gonna do now is 76 00:03:20,340 --> 00:03:23,190 to see how to subscribe to that Observable, 77 00:03:23,190 --> 00:03:25,650 that function returns an Observable, 78 00:03:25,650 --> 00:03:28,410 which will emit values or one value. 79 00:03:28,410 --> 00:03:30,660 How can I subscribe to that Observable 80 00:03:30,660 --> 00:03:33,450 to receive the value that it emits? 81 00:03:33,450 --> 00:03:34,473 This is what you do. 82 00:03:35,550 --> 00:03:37,440 You take an Observable object, 83 00:03:37,440 --> 00:03:39,930 like the one returned from that function. 84 00:03:39,930 --> 00:03:44,103 Remember this function is returning an Observable object. 85 00:03:45,150 --> 00:03:46,800 You can take that Observable object, 86 00:03:46,800 --> 00:03:49,500 and you can say ".subscribe()." 87 00:03:49,500 --> 00:03:51,420 And then you give it an object 88 00:03:51,420 --> 00:03:54,420 with three properties, three callback functions. 89 00:03:54,420 --> 00:03:57,450 A callback function properly called "next." 90 00:03:57,450 --> 00:04:00,930 This is a callback function, which will be invoked 91 00:04:00,930 --> 00:04:03,030 whenever another value is emitted. 92 00:04:03,030 --> 00:04:04,800 It's like, "Here's the next value for you." 93 00:04:04,800 --> 00:04:07,590 So the Observable will call you back. 94 00:04:07,590 --> 00:04:08,970 It'll call this function back 95 00:04:08,970 --> 00:04:12,120 whenever a new piece of data has been emitted, 96 00:04:12,120 --> 00:04:16,380 or if the Observable stream raises an error, 97 00:04:16,380 --> 00:04:18,420 then it'll call this callback. 98 00:04:18,420 --> 00:04:21,357 Okay. So you could say, "Process the error here." 99 00:04:22,290 --> 00:04:24,900 An Observable object may close. 100 00:04:24,900 --> 00:04:26,287 It might say, "That's the end of that. 101 00:04:26,287 --> 00:04:28,410 "No more data for you. I've finished." 102 00:04:28,410 --> 00:04:30,420 The Observable object can shut down, 103 00:04:30,420 --> 00:04:33,840 at which point, it'll call this function "complete." 104 00:04:33,840 --> 00:04:35,850 And this is your signal 105 00:04:35,850 --> 00:04:38,790 that there will be no more data from now on. 106 00:04:38,790 --> 00:04:41,400 So you can subscribe to an Observable, 107 00:04:41,400 --> 00:04:42,510 and you can be notified 108 00:04:42,510 --> 00:04:44,580 that the next piece of data has arrived, 109 00:04:44,580 --> 00:04:45,960 or an error has occurred, 110 00:04:45,960 --> 00:04:47,810 or that we are done here and move on. 111 00:04:49,110 --> 00:04:50,790 Okay. So let's put that into practice. 112 00:04:50,790 --> 00:04:53,370 A simple but complete example. 113 00:04:53,370 --> 00:04:56,310 Here's my code, remember, 114 00:04:56,310 --> 00:05:00,480 which creates an Observable object and returns it. 115 00:05:00,480 --> 00:05:03,120 This Observable will emit one value. 116 00:05:03,120 --> 00:05:05,220 Obviously, it's value 42. 117 00:05:05,220 --> 00:05:07,023 So I can call that function. 118 00:05:07,920 --> 00:05:09,330 When I call that function here, 119 00:05:09,330 --> 00:05:11,820 this is my main code if you like. 120 00:05:11,820 --> 00:05:12,853 When I call that function, 121 00:05:12,853 --> 00:05:15,750 it returns back an Observable object. 122 00:05:15,750 --> 00:05:18,030 I can subscribe to that Observable object 123 00:05:18,030 --> 00:05:21,810 and specify a callback inside this callback object. 124 00:05:21,810 --> 00:05:24,780 I'm only interested in handling the next value. 125 00:05:24,780 --> 00:05:27,030 Now, I could also have an error handler 126 00:05:27,030 --> 00:05:28,740 and I could have a complete handler, 127 00:05:28,740 --> 00:05:29,917 but all I'm interested in is saying, 128 00:05:29,917 --> 00:05:32,520 "Tell me when the next value was emitted." 129 00:05:32,520 --> 00:05:36,000 So what happens when this function emits the value 42? 130 00:05:36,000 --> 00:05:38,850 That value will be passed into my callback 131 00:05:38,850 --> 00:05:40,237 to say, "Here's the next value. 132 00:05:40,237 --> 00:05:45,060 "The data is 42, which I then output on the console." 133 00:05:45,060 --> 00:05:45,893 There we go. 134 00:05:45,893 --> 00:05:49,080 So that's the general way of creating an Observable 135 00:05:49,080 --> 00:05:52,500 and then subscribing to it, to receive the next value. 136 00:05:52,500 --> 00:05:54,540 Every time another value is emitted, 137 00:05:54,540 --> 00:05:56,460 this callback function will handle it. 138 00:05:56,460 --> 00:05:57,873 So that's my main code. 139 00:05:58,920 --> 00:06:01,290 In my demo, here's my main code. 140 00:06:01,290 --> 00:06:04,740 Okay. As I've advertised, call the function, 141 00:06:04,740 --> 00:06:05,910 it returns an Observable, 142 00:06:05,910 --> 00:06:09,300 and subscribe to data from that Observable. 143 00:06:09,300 --> 00:06:10,980 Oh, here's the next value. 144 00:06:10,980 --> 00:06:12,270 This is my callback function. 145 00:06:12,270 --> 00:06:15,720 A lambda that'll be invoked when that new data has arrived. 146 00:06:15,720 --> 00:06:17,070 That would be the value 42. 147 00:06:18,210 --> 00:06:20,767 Right? So I could run that sample code. 148 00:06:20,767 --> 00:06:23,790 "npx babel-node main.js" 149 00:06:23,790 --> 00:06:26,970 Okay. So babel/node will allow me to execute, 150 00:06:26,970 --> 00:06:30,423 to run my main code that we just saw, 151 00:06:31,410 --> 00:06:34,980 and it displays the value 42. 152 00:06:34,980 --> 00:06:39,840 So that is the result of this. 153 00:06:39,840 --> 00:06:43,233 Get the Observable object, subscribe to it. 154 00:06:44,550 --> 00:06:46,140 Tell me when the next value arrives. 155 00:06:46,140 --> 00:06:47,490 Oh, here's the next value? 156 00:06:47,490 --> 00:06:49,230 It's the value 42. 157 00:06:49,230 --> 00:06:52,500 Display the value 42 on the console. 158 00:06:52,500 --> 00:06:54,030 Well, there it is. 159 00:06:54,030 --> 00:06:57,540 Okay, so our Observable object was emitting the value. 160 00:06:57,540 --> 00:07:01,410 My client code subscribed to the Observable, 161 00:07:01,410 --> 00:07:03,930 got the result, displayed it on the console. 162 00:07:03,930 --> 00:07:05,463 Great. What about testing it? 163 00:07:06,480 --> 00:07:07,860 Similar kind of idea, really. 164 00:07:07,860 --> 00:07:10,713 This is my test code, in test.js. 165 00:07:12,150 --> 00:07:14,043 Test.js is here. 166 00:07:15,210 --> 00:07:19,230 So call the function as before. 167 00:07:19,230 --> 00:07:23,400 It returns an Observable, subscribe to the Observable, 168 00:07:23,400 --> 00:07:26,670 get notified when the next piece of data arrives. 169 00:07:26,670 --> 00:07:30,990 Okay. In my test, verify that the data 170 00:07:30,990 --> 00:07:35,203 that's just arrived is the correct value, and then done. 171 00:07:35,203 --> 00:07:38,100 We're getting quite used to this idea, now. 172 00:07:38,100 --> 00:07:40,350 When you have callback functions, 173 00:07:40,350 --> 00:07:43,350 Jest doesn't know how long to wait 174 00:07:43,350 --> 00:07:44,640 for the callback to be invoked. 175 00:07:44,640 --> 00:07:46,237 You need to tell it, 176 00:07:46,237 --> 00:07:48,390 "You can move on now. This test is finished." 177 00:07:48,390 --> 00:07:51,817 So I say done, and that tells Jest, 178 00:07:51,817 --> 00:07:53,730 "Okay, that's the end of that function." 179 00:07:53,730 --> 00:07:55,950 We can go onto the next test function. 180 00:07:55,950 --> 00:07:57,240 So remember, 181 00:07:57,240 --> 00:07:59,670 whenever you have some kind of callback mechanism, 182 00:07:59,670 --> 00:08:02,190 the test functions that you write, 183 00:08:02,190 --> 00:08:05,190 you have an extra parameter, a done parameter, 184 00:08:05,190 --> 00:08:09,060 a callback into Jest to tell Jest when you have finished, 185 00:08:09,060 --> 00:08:11,060 and it can move on to run the next test. 186 00:08:12,480 --> 00:08:16,923 Okay. So if I run the tests, this is what it looks like. 187 00:08:17,910 --> 00:08:18,933 I ran the test. 188 00:08:19,950 --> 00:08:22,290 It executed my test function to test 189 00:08:22,290 --> 00:08:26,313 that the Observable emitted the value 42, and it did. 190 00:08:27,270 --> 00:08:30,300 Okay, so that was a very simple example of Observable. 191 00:08:30,300 --> 00:08:33,990 We used the of() function to create an Observable object. 192 00:08:33,990 --> 00:08:36,810 We then subscribed to that Observable, 193 00:08:36,810 --> 00:08:39,817 and in our subscription, we had a "next" callback. 194 00:08:39,817 --> 00:08:41,757 "Call me back with the next value." 195 00:08:42,630 --> 00:08:45,930 We asserted that value was correct in our test. 196 00:08:45,930 --> 00:08:47,220 And then we move on. 197 00:08:47,220 --> 00:08:48,840 What we'll have a look at in the next section is 198 00:08:48,840 --> 00:08:51,690 how to look at some additional techniques to go further 199 00:08:51,690 --> 00:08:53,943 with Reactive Extensions, for JavaScript.