├── .gitignore ├── README.md ├── tsconfig.json ├── package.json ├── index.html ├── webpack.config.js └── src ├── lesson.js └── index.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Practical Rxjs features and Operators 2 | 3 | https://www.youtube.com/watch?v=2LCo926NFLI 4 | 5 | 1. Run `npm run build` 6 | 7 | 2. open the index.html in browser. 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "moduleResolution": "node", 8 | "target": "es6", 9 | "allowJs": true, 10 | "lib": [ 11 | "es2017", 12 | "dom" 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "practial", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "lesson.js", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "rxjs": "^6.2.2" 14 | }, 15 | "devDependencies": { 16 | "webpack-cli": "^3.1.0", 17 | "ts-loader": "^4.4.2", 18 | "typescript": "^2.9.2", 19 | "webpack": "^4.16.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | RxJS Demo 8 | 9 | 10 |

RxJS Demo

11 | 12 | 13 | 14 |

Combined value:

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | /* 4 | module.exports = { 5 | entry: './lesson.js', 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'bundle.js' 9 | } 10 | }; 11 | */ 12 | 13 | module.exports = { 14 | entry: './src/index.ts', 15 | devtool: 'inline-source-map', 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.tsx?$/, 20 | use: 'ts-loader', 21 | exclude: /node_modules/ 22 | } 23 | ] 24 | }, 25 | resolve: { 26 | extensions: [ '.tsx', '.ts', '.js' ] 27 | }, 28 | output: { 29 | filename: 'bundle.js', 30 | path: path.resolve(__dirname, 'dist') 31 | } 32 | }; -------------------------------------------------------------------------------- /src/lesson.js: -------------------------------------------------------------------------------- 1 | function print(val) { 2 | let el = document.createElement('p'); 3 | el.innerText = val; 4 | document.body.appendChild(el); 5 | } 6 | 7 | // const { Observable, Observer, interval, fromEvent, Subject, ReplaySubject, from, of , range, throwError } = rxjs; 8 | // const { map, filter, switchMap, tap, scan, catchError } = rxjs.operators; 9 | 10 | import { 11 | Observable, 12 | fromEvent, 13 | from, 14 | timer, 15 | interval, 16 | of, 17 | zip, 18 | forkJoin, 19 | throwError, 20 | Subject } from 'rxjs'; 21 | 22 | import { 23 | map, 24 | filter, 25 | switchMap, 26 | fromPromise, 27 | publish, 28 | finalize, 29 | tap, 30 | first, 31 | last, 32 | throttleTime, 33 | debounceTime, 34 | scan, 35 | takeUntil, 36 | takeWhile, 37 | catchError, 38 | delay, 39 | retry, 40 | multicast } from 'rxjs/operators'; 41 | 42 | const observable = Observable.create((observer) => { 43 | observer.next('hello'); 44 | observer.next('world'); 45 | observer.next('Test'); 46 | }) 47 | 48 | observable.subscribe((val) => print(val)); 49 | 50 | const clicks = fromEvent(document, 'click'); 51 | 52 | clicks.subscribe(click => console.log(click)); 53 | 54 | const promise = new Promise((resolve, reject) => { 55 | setTimeout(() => { 56 | resolve('resolved!') 57 | }, 2000) 58 | }); 59 | 60 | const obsvPromise = from(promise); 61 | 62 | obsvPromise.subscribe(result => print(result)); 63 | 64 | const alarmclock = timer(1000); 65 | 66 | alarmclock.subscribe(done => print('ding!!!')); 67 | 68 | // const myinterval = interval(1000); 69 | 70 | // myinterval.subscribe(int => print(new Date().getSeconds())); 71 | 72 | const mashup = of ('anything', ['you', 'want'], 23, true, { cool: 'stuff' }); 73 | 74 | mashup.subscribe(mashup => print(JSON.stringify(mashup))); 75 | 76 | const cold = Observable.create(observer => { 77 | observer.next(Math.random()) 78 | }) 79 | 80 | cold.subscribe(a => print(`Subscriber A: ${a}`)) 81 | cold.subscribe(b => print(`Subscriber B: ${b}`)) 82 | 83 | const x = Math.random(); 84 | const hot = Observable.create(observer => { 85 | observer.next(x); 86 | }) 87 | 88 | hot.subscribe(a => print(`Subscriber A: ${a}`)) 89 | hot.subscribe(b => print(`Subscriber B: ${b}`)) 90 | 91 | 92 | const cold2 = Observable.create(observer => { 93 | observer.next(Math.random()) 94 | }) 95 | 96 | const hot2 = cold2.pipe(publish()); 97 | 98 | hot2.subscribe(a => print(`Subscriber A: ${a}`)) 99 | hot2.subscribe(b => print(`Subscriber B: ${b}`)) 100 | 101 | hot2.connect(); 102 | 103 | const finalizeTimer = timer(1000); 104 | finalizeTimer.pipe(finalize(() => print('All done!'))).subscribe(); 105 | 106 | 107 | const finalizeInterval = interval(500).pipe(finalize(() => print('All done!'))); 108 | 109 | const subscription = finalizeInterval.subscribe(x => print('finalizeInterval:' + x)); 110 | 111 | setTimeout(() => { 112 | subscription.unsubscribe() 113 | }, 3000); 114 | 115 | const numbers = of(10, 100, 1000); 116 | 117 | numbers.pipe( 118 | map(num => Math.log(num))) 119 | .subscribe(x => print(x)); 120 | 121 | const jsonString = '{ "type": "Dog", "breed": "Pug" }'; 122 | const apiCall = of(jsonString); 123 | 124 | apiCall.pipe(map(json => JSON.parse(json))) 125 | .subscribe(obj => { 126 | print(obj.type); 127 | print(obj.breed); 128 | }) 129 | 130 | const names = of('Simon', 'Garfunkle'); 131 | 132 | names 133 | .pipe( 134 | tap(name => print(name)), 135 | map(name => name.toUpperCase()), 136 | tap(name => print(name))) 137 | .subscribe(); 138 | 139 | const numbersv2 = of(-3, 5, 7, 2, -7, 9, -2); 140 | 141 | numbersv2.pipe( 142 | filter(n => n >= 0)).subscribe(n => print(n)); 143 | 144 | numbersv2.pipe(first()).subscribe(n => print(n)); 145 | 146 | numbersv2.pipe(last()).subscribe(n => print(n)); 147 | 148 | let mouseEvents = fromEvent(document, 'mousemove'); 149 | 150 | mouseEvents.pipe(throttleTime(1000)) 151 | .subscribe(e => print(e.type)); 152 | 153 | mouseEvents.pipe(debounceTime(1000)) 154 | .subscribe(e => print(e.type)); 155 | 156 | let gameClicks = fromEvent(document, 'click'); 157 | 158 | gameClicks.pipe( 159 | map(e => parseInt(Math.random() * 10)), 160 | tap(score => print(`Click scored + ${score}`)), 161 | scan((highScore, score) => highScore + score)) 162 | .subscribe(highScore => print(`High Score ${highScore}`)); 163 | 164 | 165 | let intervalClicks = fromEvent(document, 'click'); 166 | 167 | clicks.pipe( 168 | switchMap(click => { 169 | return interval(500) 170 | })).subscribe(i => print(i)); 171 | 172 | const intervaltick = interval(500); 173 | const notifier = timer(2000); 174 | 175 | intervaltick.pipe(takeUntil(notifier)); 176 | 177 | 178 | const namestakewhile = of('Bob', 'Jeff', 'Doug', 'Steve'); 179 | 180 | namestakewhile.pipe( 181 | takeWhile(name => name != 'Doug'), 182 | finalize(() => print('Complete! I found Doug'))) 183 | .subscribe(i => print(i)); 184 | 185 | const yin = of('peanut butter', 'wine', 'rainbows'); 186 | const yang = of('jelly', 'cheese', 'unicorns'); 187 | 188 | const combo = zip(yin, yang); 189 | 190 | combo.subscribe(arr => print(arr)); 191 | 192 | const yinv2 = of('peanut butter', 'wine', 'rainbows'); 193 | const yangv2 = of('jelly', 'cheese', 'unicorns').pipe(delay(2000)); 194 | 195 | const combov2 = forkJoin(yin, yang); 196 | 197 | combov2.subscribe(arr => print(arr)); 198 | 199 | const throwErrorObservable = throwError('catch me!'); 200 | throwErrorObservable.pipe( 201 | catchError(err => print(`Error caught: ${err}`)), 202 | retry(2)) 203 | .subscribe(val => print(val), e => print(e)); 204 | 205 | const subject = new Subject(); 206 | const subA = subject.subscribe(val => print(`Sub A: ${val}`)); 207 | const subB = subject.subscribe(val => print(`Sub B: ${val}`)); 208 | 209 | subject.next('Hello'); 210 | 211 | setTimeout(() => { 212 | subject.next('World'); 213 | }, 1000); 214 | 215 | const observableforMulticast = fromEvent(document, 'click'); 216 | 217 | const clicks = observableforMulticast.pipe( 218 | tap(_ => print('Do One Time!')), 219 | multicast(() => new Subject()) 220 | ); 221 | 222 | const subAformulti = clicks.subscribe(c => print(`Sub A: ${c.timeStamp}`)); 223 | const subBformulti = clicks.subscribe(c => print(`Sub B: ${c.timeStamp}`)); 224 | 225 | clicks.connect(); -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Observable, 3 | Observer, 4 | fromEvent, 5 | from, 6 | timer, 7 | interval, 8 | of, 9 | zip, 10 | forkJoin, 11 | throwError, 12 | Subject 13 | } from 'rxjs'; 14 | 15 | import { 16 | map, 17 | filter, 18 | switchMap, 19 | mergeMap, 20 | publish, 21 | finalize, 22 | tap, 23 | first, 24 | last, 25 | throttleTime, 26 | debounceTime, 27 | scan, 28 | takeUntil, 29 | takeWhile, 30 | catchError, 31 | delay, 32 | retry, 33 | multicast 34 | } from 'rxjs/operators'; 35 | 36 | function print(val: string) { 37 | let el = document.createElement('p'); 38 | el.innerText = val; 39 | document.body.appendChild(el); 40 | } 41 | 42 | 43 | const observable = Observable.create((observer: Observer) => { 44 | observer.next('hello'); 45 | observer.next('world'); 46 | observer.next('Test'); 47 | observer.complete(); 48 | }) 49 | 50 | observable.subscribe((val: string) => print(val)); 51 | 52 | const clicks = fromEvent(document, 'click'); 53 | 54 | clicks.subscribe(click => console.log(click)); 55 | 56 | const promise = new Promise((resolve, reject) => { 57 | setTimeout(() => { 58 | resolve('resolved!') 59 | }, 2000) 60 | }); 61 | 62 | const obsvPromise = from(promise); 63 | 64 | obsvPromise.subscribe((result: string) => print(result)); 65 | 66 | const alarmclock = timer(1000); 67 | 68 | alarmclock.subscribe(done => print('ding!!!')); 69 | 70 | const myinterval = interval(1000); 71 | 72 | myinterval.subscribe(int => print((new Date().getSeconds()).toString())); 73 | 74 | const mashup = of('anything', ['you', 'want'], 23, true, { cool: 'stuff' }); 75 | 76 | mashup.subscribe(mashup => print(JSON.stringify(mashup))); 77 | 78 | const cold = Observable.create((observer: Observer) => { 79 | observer.next(Math.random()) 80 | }) 81 | 82 | cold.subscribe((a: number) => print(`Subscriber A: ${a}`)) 83 | cold.subscribe((b: number) => print(`Subscriber B: ${b}`)) 84 | 85 | const x = Math.random(); 86 | const hot = Observable.create((observer: Observer) => { 87 | observer.next(x); 88 | }) 89 | 90 | hot.subscribe((a: number) => print(`Subscriber A: ${a}`)) 91 | hot.subscribe((b: number) => print(`Subscriber B: ${b}`)) 92 | 93 | 94 | const cold2 = Observable.create((observer: Observer) => { 95 | observer.next(Math.random()) 96 | }) 97 | 98 | const hot2 = cold2.pipe(publish()); 99 | 100 | hot2.subscribe((a: number) => print(`Subscriber A: ${a}`)) 101 | hot2.subscribe((b: number) => print(`Subscriber B: ${b}`)) 102 | 103 | hot2.connect(); 104 | 105 | const finalizeTimer = timer(1000); 106 | finalizeTimer.pipe(finalize(() => print('All done!'))).subscribe(); 107 | 108 | 109 | const finalizeInterval = interval(500).pipe(finalize(() => print('All done!'))); 110 | 111 | const subscription = finalizeInterval.subscribe(x => print('finalizeInterval:' + x)); 112 | 113 | setTimeout(() => { 114 | subscription.unsubscribe() 115 | }, 3000); 116 | 117 | const numbers = of(10, 100, 1000); 118 | 119 | numbers.pipe( 120 | map(num => Math.log(num))) 121 | .subscribe(x => print(x.toString())); 122 | 123 | const jsonString = '{ "type": "Dog", "breed": "Pug" }'; 124 | const apiCall = of(jsonString); 125 | 126 | apiCall.pipe(map(json => JSON.parse(json))) 127 | .subscribe(obj => { 128 | print(obj.type); 129 | print(obj.breed); 130 | }) 131 | 132 | const names = of('Simon', 'Garfunkle'); 133 | 134 | names 135 | .pipe( 136 | tap(name => print(name)), 137 | map(name => name.toUpperCase()), 138 | tap(name => print(name))) 139 | .subscribe(); 140 | 141 | const numbersv2 = of(-3, 5, 7, 2, -7, 9, -2); 142 | 143 | numbersv2.pipe( 144 | filter(n => n >= 0)).subscribe(n => print(n.toString())); 145 | 146 | numbersv2.pipe(first()).subscribe(n => print(n.toString())); 147 | 148 | numbersv2.pipe(last()).subscribe(n => print(n.toString())); 149 | 150 | let mouseEvents = fromEvent(document, 'mousemove'); 151 | 152 | mouseEvents.pipe(throttleTime(1000)) 153 | .subscribe(e => print(e.type)); 154 | 155 | mouseEvents.pipe(debounceTime(1000)) 156 | .subscribe(e => print(e.type)); 157 | 158 | let gameClicks = fromEvent(document, 'click'); 159 | 160 | gameClicks.pipe( 161 | map(e => parseInt((Math.random() * 10).toString(), 10)), 162 | tap(score => print(`Click scored + ${score}`)), 163 | scan((highScore, score) => highScore + score)) 164 | .subscribe(highScore => print(`High Score ${highScore}`)); 165 | 166 | 167 | let intervalClicks = fromEvent(document, 'click'); 168 | 169 | intervalClicks.pipe( 170 | switchMap(click => { 171 | return interval(500) 172 | })).subscribe(i => print(i.toString())); 173 | 174 | const intervaltick = interval(500); 175 | const notifier = timer(2000); 176 | 177 | intervaltick.pipe(takeUntil(notifier)); 178 | 179 | 180 | const namestakewhile = of('Bob', 'Jeff', 'Doug', 'Steve'); 181 | 182 | namestakewhile.pipe( 183 | takeWhile(name => name != 'Doug'), 184 | finalize(() => print('Complete! I found Doug'))) 185 | .subscribe(i => print(i)); 186 | 187 | const yin = of('peanut butter', 'wine', 'rainbows'); 188 | const yang = of('jelly', 'cheese', 'unicorns'); 189 | 190 | const combo = zip(yin, yang); 191 | 192 | combo.subscribe(arr => print(arr.toString())); 193 | 194 | const yinv2 = of('peanut butter', 'wine', 'rainbows'); 195 | const yangv2 = of('jelly', 'cheese', 'unicorns').pipe(delay(2000)); 196 | 197 | const combov2 = forkJoin(yin, yang); 198 | 199 | combov2.subscribe(arr => print(arr.toString())); 200 | 201 | const throwErrorObservable = throwError('catch me!'); 202 | throwErrorObservable.pipe( 203 | catchError(err => of(`Error caught: ${err}`)), 204 | retry(2)) 205 | .subscribe((val: string) => print(val), e => print(e)); 206 | 207 | const subject = new Subject(); 208 | const subA = subject.subscribe(val => print(`Sub A: ${val}`)); 209 | const subB = subject.subscribe(val => print(`Sub B: ${val}`)); 210 | 211 | subject.next('Hello'); 212 | 213 | setTimeout(() => { 214 | subject.next('World'); 215 | }, 1000); 216 | 217 | const observableforMulticast = fromEvent(document, 'click'); 218 | 219 | const multiCastClicks: any = observableforMulticast.pipe( 220 | tap(_ => print('Do One Time!')), 221 | multicast(() => new Subject()) 222 | ); 223 | 224 | const subAformulti = multiCastClicks.subscribe((c: any) => print(`Sub A: ${c.timeStamp}`)); 225 | const subBformulti = multiCastClicks.subscribe((c: any) => print(`Sub B: ${c.timeStamp}`)); 226 | 227 | multiCastClicks.connect(); 228 | 229 | const input1 = document.querySelector('#input1'); 230 | const input2 = document.querySelector('#input2'); 231 | 232 | const span = document.querySelector('span'); 233 | 234 | const obsInput1 = fromEvent(input1, 'input'); 235 | const obsInput2 = fromEvent(input2, 'input'); 236 | 237 | obsInput1.pipe( 238 | mergeMap( 239 | event1 => obsInput2.pipe( 240 | map(event2 => (event1.target).value + ' ' + (event2.target).value) 241 | ) 242 | ) 243 | ).subscribe( 244 | combinedValue => { span.textContent = combinedValue; console.log('test'); } 245 | ); 246 | 247 | 248 | const numbersMerge1 = of(1, 2, 3); 249 | 250 | const numbersMerge2 = of(5, 10, 15); 251 | 252 | numbersMerge1.pipe( 253 | mergeMap( 254 | number1 => numbersMerge2.pipe( 255 | map(number2 => number1 * number2) 256 | ) 257 | ) 258 | ).subscribe( 259 | combined => print(combined.toString()) 260 | ); 261 | 262 | --------------------------------------------------------------------------------