---
# System prepended metadata

title: 'MaxM, RxJS'
tags: [MaxM, ' rxjs']

---

---
title: MaxM, RxJS
tags: MaxM, rxjs
---

# RxJS och Observables
## Subscriptions

---

## Vad gör RxJS

* Hanterar _event streams_
* En massa operatorer
    * Monadiska operatorer som flatMap, map, etc.
    * Retry, delay, combine
    * Mycket, mycket mer... (se [API dox](https://rxjs.dev/api))

---

## Observable
![](https://i.imgur.com/AzqJAxD.png)


---

## Subscribe

* Man måste anropa _.subscribe()_ för att kicka igång
* Subscription måste avslutas, annars får man minnesläckor
* 3 olika sätt
    * _subscription.unsubscribe()_
    * _observable.complete()_ (avslutar subscription automatiskt) 
    * operationer som t.ex _take(1)_ (gör _complete()_ => avslutar subscription)
    
* [Best Practices for Managing RxJS Subscriptions](https://www.thisdot.co/blog/best-practices-for-managing-rxjs-subscriptions)

---

## Exempel take()

```typescript
o.pipe(
  take(1)
).subscribe(x => {
    // Do stuff with 'x'
})
```

---

## Exempel unsubscribe()

```typescript
private subscr: Subscription
:
this.subscr = o.subscribe(x => {
    // Do stuff with 'x'
})
:
ngOnDestroy() {
    this.subscr.unsubscribe();
}
```

---

## Exempel unsubscribe(), flera i en

```typescript
private subscr = new Subscription();
:
this.subscr.add(o.subscribe(x => {
    // Do stuff with 'x'
}))
:
ngOnDestroy() {
    this.subscr.unsubscribe();
}
```

---

## Angularspecifikt

* HttpClient-metoder (get, post, etc) 
    * returnerar Observable
    * gör alltid _complete()_ internt
    * man behöver alltså inte själv anropa _unsubscribe()_

* AsyncPipe (t.ex `<div>{{myObservable$ | async}})</div>`)
    * Gör automatisk subscribe/unsubscribe
    * OBS! använd inte för HTTP-anrop

---

## Exempel async
my.component.ts:
```typescript
private myObservable$: Observable<SomeType>
:
ngOnInit() {
    this.myObservable$ = this.someService.getSomeObservable$().pipe(
      map(someMapping())
    )    
}

```
my.component.html:
```html
<div">
  {{myObservable$ | async}}
</div>
```

---

## Exempel async, *ngIf
my.component.ts:
```typescript
private meetingDetails$: Observable<MeetingDetails>
:
ngOnInit() {
    this.meetingDetails$ = this.someService.getOneMeetingDetails().pipe(
      map(someMapping())
    )    
}
```
my.component.html:
```html
<!-- Vänta till meetingDetails$ har fått ett värde och 
  bind värdet till 'meetingDetails'-->
<div *ngIf="meetingDetails$ | async as meetingDetails">

  {{meetingDetails.id}}
</div>
```

---

## Exempel async, list-objekt med *ngFor
my.component.ts:
```typescript
private meetingDetailsList$: Observable<List<MeetingDetails>>
:
ngOnInit() {
    this.meetingDetailsList$ = this.someService.getListOfMeetingDetails().pipe(
      map(someMapping())
    )    
}
```
my.component.html:

```html
<div *ngFor="let meetingDetails meetingDetailsList$ | async">
  {{meetingDetails.id}}
</div>
```

---

## Andra bra operatorer

combineLatest()

```typescript

ngOnInit() {
    this.combined$ = combineLatest(
        [
            this.someService.getObs1$(),
            this.someService.getObs2$()
        ]).pipe(
          map(([o1,o2]) => {
            // Do stuff with o1 and o2  
          })
        )
    )    
}
```


---
    
## Andra bra operatorer

mergeMap(), flatMap()

```typescript

ngOnInit() {
    this.myObservable$ = this.someService.getSomeObservable$().pipe(
      mergeMap(x => this.anotherService.getAnotherObservable$(x))
    )   
}
```

---

## Andra bra operatorer

switchMap()

```typescript

ngOnInit() {
    this.myObservable$ = this.someService.getSomeObservable$().pipe(
      // get is cancelled completed in case of new event
      switchMap(x => this.httpClient.get(<some get based on x>)) 
    )   
    
    this.someService.getSomeObservable$().toPromise()
}
```
---