Pages

Showing posts with label Angular. Show all posts
Showing posts with label Angular. Show all posts

Thursday, August 18, 2022

Rxjs - handling multiple requests and subtle differences of respective operators and higher order observable

OPTION 1:  PARALLEL

You might use forkJoin or mergeMap.

1) forkJoin([observable 1, observable 2]): can only trigger if ALL observable completed. Input can be array or object of an observable.

=> Perfect if you have a couple number of HTTP requests or any kind of asynchronous operations. It works like Promise.all([]).


Demo here

Multiple request with mergeMap (see explanation below)




OPTION 2: SEQUENTIAL

concatMap (triggered by order)

 

some other combination operators: 

1) combineLatest([observable1, observable2]): just works without caring about the completion of streams. Input can be array or object of observable. It will be trigger if ONE of the streams emitting new value.

2) zip([observable1, observable2, observablen...]): Combine each corresponding data from different streams into one object/array.

See https://stackblitz.com/edit/typescript-5az27c?devtoolsheight=100&file=index.ts

3) concat 

Combine different observable one by after completion IN ORDER.

4) merge

Combine different observable and emit NOT IN ORDER

5) race : Reset the "circle" of emission each time it is completed.

6) withLatestForm (operator)

RxJS Higher Order Observables (HOOs):

(Receive Outer Observable ==> Emit/Return Inner Observable)

7) switchMap, mergeMap, concatMap, exhaustMap

switchMap    = switchAll + map
mergeMap    = mergeAll + map
concatMap    = concatAll + map
exhaustMap  = exhaustAll + map

Using these HOO, you don't have to use nested subscribe when you use nested observable.

- switchMap cancels previous HTTP requests that are still in progress, while mergeMap lets all of them finish.

concatMap does not subscribe to the next observable until the previous completes

- exhaustMap:  ignore other values until that observable completes.

Note: FlatMap is an alias of mergeMap

Example 1:  example
Example 2:  example 

10 common operators: 

map,  filter, tap, switchMap, concatMap, combineLatest, startWith, distinctUntilChanged, debounceTime,  catchError

Source: https://www.youtube.com/watch?v=Byttv3YpjQk&ab_channel=JoshuaMorony

References:

https://blog.angular-university.io/rxjs-higher-order-mapping/

https://riptutorial.com/rxjs/example/27973/sending-multiple-parallel-http-requests

https://indepth.dev/reference/rxjs/operators/merge-map

https://vdsabev.medium.com/the-simple-difference-between-rxjs-switchmap-and-mergemap-397c311552a5#

https://luukgruijs.medium.com/understanding-rxjs-map-mergemap-switchmap-and-concatmap-833fc1fb09ff#

https://www.youtube.com/playlist?list=PLxnmNhAZjt7y9u9xum0SIvz1_p09AP019

https://www.youtube.com/watch?v=qYdKmYp95Jg&ab_channel=DecodedFrontend

https://www.youtube.com/watch?v=qChj6nScvl0&ab_channel=ChauTran

https://github.com/angular-vietnam/100-days-of-angular/blob/master/Day025-rxjs-hoo-utility.md

https://www.youtube.com/watch?v=Byttv3YpjQk&ab_channel=JoshuaMorony

https://rxmarbles.com/

https://www.youtube.com/watch?v=ak3MvMn8u18


Wednesday, August 17, 2022

RXJS operator: toArray() - Combine individual value/item to an array

 The main different between "of" and "from" provided by Rxjs is that "of" emits all data once but "from" prints out data one by one rather than the whole sequence.

In case you use from() but still want to emit data in the form of an array, then toArray() is here to rescue.



Tuesday, August 16, 2022

Convert RXJS's observable to Promise and vice verse

In case you want to "mix" RXJS with promise-based approach, then firstValueForm or lastValueForm are here to rescue. Both can be imported from "rxjs" library.

See the code for converting observable to Promise. As await function can only be written inside an async function, you need to put them in a function started with the keyword async as normal.


What if you want to convert from promise to observable? Simply use "from(promise)" imported directly from "rxjs" and pass the promise as the parameter. Take a look at the following image:


The data is a promise-based one and returned from server using axios.

It is worth noting that both lastValueFrom() and firstValueFrom() can only get 1 emitted value. You might use async subscribe to get the whole data instead in case you want to use it somewhere else. Take a look at the image below:



FYI toPromise() is being deprecated in RxJS 7 and will be removed in RxJS 8

Saturday, July 2, 2022

Publish Angular-based app to Netlify - Fix 404

 While I have no issue when attempting to publish React or Vue-based app to Netlify, there is a tiny configuration that is needed when you push and deploy code to this platform.

Running "ng build" will generate a folder often named "dist" and a (another) nested folder named as "my-app" (You might change it for sure but that is the one by default). So you need to configure as follows so that Netlify can successfully launch your page.


Netlify verion: https://vietnameselanguage.netlify.app/

Vercel.com version https://vietnameselanguage.org

Wednesday, June 8, 2022

@ViewChild in Angular

Using display:none in Angular does not completely remove the elements in the DOM. It is still there and ready to be "re-active" using JavaScript. So you need *ngIf if in this case.

When conditional rendering data using *ngIf in Angular (>=2), you cannot query the DOM inside and at the same time appending something to those elements inside. 

You might need to use the decorator @ViewChild() such as in follows: 

 @ViewChild('control_bottom_html')  control_bottom_variable: ElementRef;

You need to declare  #control_bottom_html (with the hashtag) in the DOM where you want to manipulate directly whereas control_bottom_variable is the variable that can be then used to update the DOM already injected. 

Now inside the phrase  ngAfterViewInit() (not the phrase ngOnInit()) , you can call query the div injected with #control_bottom_html.

 this.controlPanel = this.control_bottom_variable.nativeElement; 

Then you can manipulate it such as appending elements or implements events.

From Angular Docs, it seems that you should use Render2 rather than ElementRef for safety reason.

https://angular.io/api/core/ElementRef