From e4ae6f6010b84445a7c1f520a3c18da00d172eb0 Mon Sep 17 00:00:00 2001 From: Captain Storm Date: Wed, 25 Aug 2021 23:58:22 -0700 Subject: [PATCH 1/4] Initial commit --- .gitattributes | 2 ++ package-lock.json | 3 ++- src/app/about/about.component.ts | 46 ++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/package-lock.json b/package-lock.json index 3513028a..f1e5e10f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6245,7 +6245,8 @@ }, "ini": { "version": "1.3.5", - "resolved": "", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts index 6bf01d19..bebf7183 100644 --- a/src/app/about/about.component.ts +++ b/src/app/about/about.component.ts @@ -27,14 +27,56 @@ export class AboutComponent implements OnInit { ngOnInit() { + /* + every click that you do in the app that will be a stream + of values containing the click event + */ - } + document.addEventListener('click', evt => { + console.log(evt) + }) + /* + F12 + so what we see here is whnever we click on the mouse is + an example of a stream of values that are being emitted + over time + */ + + // emitting a value each second + // we will define a variable, + // then we will ini to 0 and + // we are going to emit a new value over time + // and increment the counter each time that we emit our value + let counter = 0; + setInterval(() => { + console.log(counter); + counter++; + }, 1000); -} + /* now we have 2 independent streams of values + clicks and interval. + Let's add another type of stream: setTimeout + */ + // this is async operation + // this stream emits only one value and then completes it + // setTimeout emits a value and completes + // the other 2 emit multiple values and never complete + setTimeout(() => { + console.log('finished ... ') + }, 3000) + } +} +/* +setInterval continuesly emits the values +click streams only when clicked on +setTimeout finishes exectuting after 3 seconds +click and setInterval are multi value streams +they continuesly emit and they never compelte +*/ From 348c18e6158d7b3ef5e6b7edec6887c1b526433b Mon Sep 17 00:00:00 2001 From: Captain Storm Date: Thu, 26 Aug 2021 00:10:31 -0700 Subject: [PATCH 2/4] 1-7 what problem RXJS solves --- src/app/about/about.component.ts | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts index bebf7183..0380784c 100644 --- a/src/app/about/about.component.ts +++ b/src/app/about/about.component.ts @@ -80,3 +80,38 @@ setTimeout finishes exectuting after 3 seconds click and setInterval are multi value streams they continuesly emit and they never compelte */ + + + +/* +Video 6 - what is Rxjs and what problem it solves + +1. combine all 3 streams together +2. after a user clicks on the certain part of the screen +3. we might want to wait for 3 seconds and only then emit the interval + +*/ + +/* ----- callback hell ---- */ +/* + document.addEventListener('click', evt => { + console.log(evt); + + setTimeout(() => { + console.log('finished ... '); + + + let counter = 0; + setInterval( ()=> { + console.log(counter); + counter++; + }, 1000) + }, 3000) + }) + + this block of code will not work until you click + somewhere on the screen + + you will see a duplicate execution + if you click on the screen multiple times +*/ From ce55fa5dbddfe8cb98601a123465f01778fc2dd3 Mon Sep 17 00:00:00 2001 From: Captain Storm Date: Tue, 31 Aug 2021 21:20:14 -0700 Subject: [PATCH 3/4] Update about.component.ts --- src/app/about/about.component.ts | 87 +------------------------------- 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts index 0380784c..af772210 100644 --- a/src/app/about/about.component.ts +++ b/src/app/about/about.component.ts @@ -25,93 +25,8 @@ import {createHttpObservable} from '../common/util'; }) export class AboutComponent implements OnInit { - ngOnInit() { + ngOnInit() { - /* - every click that you do in the app that will be a stream - of values containing the click event - */ - - document.addEventListener('click', evt => { - console.log(evt) - }) - - /* - F12 - so what we see here is whnever we click on the mouse is - an example of a stream of values that are being emitted - over time - */ - - // emitting a value each second - // we will define a variable, - // then we will ini to 0 and - // we are going to emit a new value over time - // and increment the counter each time that we emit our value - let counter = 0; - setInterval(() => { - console.log(counter); - counter++; - }, 1000); - - - /* now we have 2 independent streams of values - clicks and interval. - Let's add another type of stream: setTimeout - */ - - // this is async operation - // this stream emits only one value and then completes it - // setTimeout emits a value and completes - // the other 2 emit multiple values and never complete - - setTimeout(() => { - console.log('finished ... ') - }, 3000) } } - -/* -setInterval continuesly emits the values -click streams only when clicked on -setTimeout finishes exectuting after 3 seconds - -click and setInterval are multi value streams -they continuesly emit and they never compelte -*/ - - - -/* -Video 6 - what is Rxjs and what problem it solves - -1. combine all 3 streams together -2. after a user clicks on the certain part of the screen -3. we might want to wait for 3 seconds and only then emit the interval - -*/ - -/* ----- callback hell ---- */ -/* - document.addEventListener('click', evt => { - console.log(evt); - - setTimeout(() => { - console.log('finished ... '); - - - let counter = 0; - setInterval( ()=> { - console.log(counter); - counter++; - }, 1000) - }, 3000) - }) - - this block of code will not work until you click - somewhere on the screen - - you will see a duplicate execution - if you click on the screen multiple times -*/ From 3dcd1177fea84017f1b3b3eae15cc58f3ef32212 Mon Sep 17 00:00:00 2001 From: Captain Storm Date: Tue, 31 Aug 2021 23:24:49 -0700 Subject: [PATCH 4/4] update dialog --- .../course-dialog/course-dialog.component.ts | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/app/course-dialog/course-dialog.component.ts b/src/app/course-dialog/course-dialog.component.ts index 6d3017fa..215763b8 100644 --- a/src/app/course-dialog/course-dialog.component.ts +++ b/src/app/course-dialog/course-dialog.component.ts @@ -40,10 +40,94 @@ export class CourseDialogComponent implements AfterViewInit { } - ngAfterViewInit() { + /** + * we are going to show that Merge is ideal for performing + * HTTP requests in parallel, as we have seen before, + * use of concat map here is ensuring that our first + * course save is going to be completed before issuing + * the second one. + * This is the logic that we want here for save operations. + * ngOnInit() { + this.form.valueChanges + .pipe( + filter(() => this.form.valid), + concatMap(changes => this.saveCourse(changes)) + ) + .subscribe(); + } + * But if you find yourself in a situation where you would + * like to perform multiple calls to your backend in parallel + * and fetch the results of each call as they arrive over time, + * then in that case you canstill use here the merge map operator. + */ + + /** + * Merge map is very similar to concat map that we already covered. + * The principle is the same. We are going to take the values + * of the source observable and we are going to apply a mapping + * function that is going to take the value and it's going to + * produce a new observable. So here the value one was taken + * and by running this function here, we have created here a + * new observable which takes the value multiply it by ten + * and then terminates the observable, + * the observable gets completed. + * + */ + + + /** + * So remember before we were using concat map so the save + * operations would all work sequentially. + * We will have to wait for the save to complete in order to + * proceed and perform the next save. + * If instead of concat map we use merge map, + * the behavior is going to be different. + * Let's switch over here to a larger window and tried to issue + * several saves. + * In parallel, we are here on the network, so let's now type + * in here title over the course so that we can emit multiple + * observables. + * As you can see here in the waterfall diagram, + * we have several requests running in parallel. + * At the same time, we are not waiting for one request to + * complete before launching another. + * So the merge map operator is ideal for performing HTTP requests + * in parallel. + * However, in the concrete scenario of a save, we want + * really to make sure that the save is completed + * before performing a second save. + * So if the order of the observable values is important, + * then we should use concat map. + * If we want to perform our observables in parallel, + * then we use merge map. + * And with these we have given the concat map and the merge map + * operators. What we are going to do next is we are going + * to cover two other very commonly used mapping operators + * exhaust map and switch map. + */ + + ngOnInit() { + this.form.valueChanges + .pipe( + filter(() => this.form.valid), + mergeMap(changes => this.saveCourse(changes)) + ) + .subscribe(); + } + + saveCourse(changes) { + return fromPromise(fetch(`/api/courses/${this.course.id}`, { + method: 'PUT', + body: JSON.stringify(changes), + headers: { + 'content-type': 'application/json' + } + })); } + ngAfterViewInit() {} + save() { this.store.saveCourse(this.course.id, this.form.value) .subscribe(