BugFixing: Async loading
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
index c352742..91c74ce 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
@@ -28,7 +28,7 @@
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 import { ActionsSubject, Store } from '@ngrx/store';
 import { DisableAction, EnableAction, SetUserDefinedPropertyAction } from 'ngrx-forms';
-import { of } from 'rxjs';
+import { of, ReplaySubject } from 'rxjs';
 import { INITIAL_STATE, FORM_ID, GAS_BRANCH_ID_KEY } from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer';
 import * as distributionGroupActions from '@grid-failure-information-app/shared/store/actions/distribution-groups.action';
 
@@ -456,9 +456,10 @@
     const failureHousenumber = new FailureHousenumber();
     failureHousenumber.housenumber = 'test';
     failureHousenumber.uuid = 'hello';
-    service.addressHouseNumbers = [failureHousenumber];
+    service['_addressHouseNumbers$'] = new ReplaySubject<FailureHousenumber[]>();
+    service['_addressHouseNumbers$'].next([failureHousenumber]);
     const hsnr = 'test';
-    service.setLatLong(hsnr);
+    service['_setLatLong'](hsnr);
 
     expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureAddress({ payload: failureHousenumber.uuid }));
   });
@@ -768,7 +769,7 @@
   });
 
   it('should dispatch action in response to controlId = gridFailureDetailsForm.housenumber', () => {
-    const spy: any = spyOn(service, 'setLatLong');
+    const spy: any = spyOn<any>(service, '_setLatLong');
     let formState: any = {
       id: 'gridFailureDetailsForm',
       value: {
@@ -795,7 +796,7 @@
   });
 
   it('should dispatch action in response to controlId = gridFailureDetailsForm', () => {
-    const spy: any = spyOn(service, 'loadInitialAddressData');
+    const spy: any = spyOn<any>(service, '_loadInitialAddressData');
     let formState: any = {
       id: 'gridFailureDetailsForm',
       value: {
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.ts
index 25d423e..7b579a8 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.ts
@@ -49,7 +49,7 @@
   unbox,
   MarkAsPristineAction,
 } from 'ngrx-forms';
-import { combineLatest, Observable, of } from 'rxjs';
+import { combineLatest, Observable, of, ReplaySubject } from 'rxjs';
 import { debounceTime, distinctUntilChanged, map, skipWhile, take, takeUntil, tap } from 'rxjs/operators';
 import { StateEnum } from '@grid-failure-information-app/shared/constants/enums';
 
@@ -85,7 +85,7 @@
   public noBranchId: string;
   public powerBranchId: string;
   public isFieldRequiredDependingOnBranchId: boolean = false;
-
+  private _testCounter = 0;
   public addressCommunities$: Observable<Array<string>> = this.actionsSubject.pipe(
     ofType(gridFailureActions.loadAllAddressCommunitiesSuccess),
     map(action => {
@@ -110,22 +110,21 @@
     }),
     takeUntil(this._endSubscriptions$)
   );
-  public addressHouseNumbers$: Observable<Array<string>> = this.actionsSubject.pipe(
-    ofType(gridFailureActions.loadAddressHouseNumbersSuccess),
-    map(action => action.payload),
-    map(payload => payload.map(adrs => adrs.housenumber)),
-    takeUntil(this._endSubscriptions$)
+
+  private _addressHouseNumbers$: ReplaySubject<Array<models.FailureHousenumber>> = new ReplaySubject<Array<models.FailureHousenumber>>();
+  public addressHouseNumbers$: Observable<Array<string>> = this._addressHouseNumbers$.pipe(
+    map((hnrs: models.FailureHousenumber[]) => hnrs.map(hnr => hnr.housenumber))
   );
 
   public addressPostCodes$: Observable<Array<string>> = this.actionsSubject.pipe(
     ofType(gridFailureActions.loadAddressPostalcodesSuccess),
+
     map(action => {
       const stringArray = action.payload;
       return stringArray.sort(sortAlphaNum);
     }),
     takeUntil(this._endSubscriptions$)
   );
-  public addressHouseNumbers: Array<models.FailureHousenumber>;
   public showQualifyButton: boolean = false;
   public showStornoButton: boolean = false;
   public showCreatedButton: boolean = false;
@@ -207,7 +206,10 @@
   public dateValueConverter = NgrxValueConverters.objectToJSON;
   private _registerLoadGridFailureExpectedReasons(): void {
     combineLatest(this.gridFailureBranches$, this.gridFailureDetailsFormState$)
-      .pipe(skipWhile(([branches, formState]) => !this.currentFormState || branches.length === 0))
+      .pipe(
+        skipWhile(([branches, formState]) => !this.currentFormState || branches.length === 0),
+        takeUntil(this._endSubscriptions$)
+      )
       .subscribe(([branches, formState]) => {
         let currentBranch = branches.find(branch => !!formState && branch.id === formState.value.branchId);
         this.currentFormState.value.branchId !== formState.value.branchId && !!currentBranch && this.loadGridFailureExpectedReasons(currentBranch);
@@ -216,7 +218,8 @@
     combineLatest(this.gridFailureBranches$, this.gridFailureDetailsFormState$)
       .pipe(
         skipWhile(([branches, formState]) => !formState || branches.length === 0),
-        take(1)
+        take(1),
+        takeUntil(this._endSubscriptions$)
       )
       .subscribe(([branches, formState]) => {
         let currentBranch = branches.find(branch => branch.id === formState.value.branchId);
@@ -229,13 +232,50 @@
   }
 
   public loadStations(): void {
+    this.actionsSubject
+      .pipe(
+        ofType(gridFailureActions.loadStationsSuccess),
+        take(1),
+        map(action => action.payload),
+        takeUntil(this._endSubscriptions$)
+      )
+      .subscribe((stations: Array<models.FailureStation>) => {
+        this._stations = stations;
+      });
     this.appState$.dispatch(gridFailureActions.loadStations());
   }
 
   public loadGridFailureVersions(gridFailureId: string): void {
+    this.actionsSubject
+      .pipe(
+        ofType(gridFailureActions.loadGridFailureVersionsSuccess),
+        take(1),
+        takeUntil(this._endSubscriptions$),
+        map(action => {
+          const gridFailures: models.GridFailure[] = action['payload'];
+          return !!gridFailures && Math.max(...gridFailures.map(o => o.versionNumber));
+        })
+      )
+      .subscribe(versionNumber => {
+        this.maxVersionNumber = versionNumber;
+      });
     this.appState$.dispatch(gridFailureActions.loadGridFailureVersions({ payload: gridFailureId }));
   }
 
+  public loadDistributionGroups(): void {
+    this.actionsSubject
+      .pipe(
+        ofType(gridFailureActions.loadGridFailureDistributionGroupsSuccess),
+        take(1),
+        map(action => action.payload),
+        takeUntil(this._endSubscriptions$)
+      )
+      .subscribe((assignedGroups: Array<models.DistributionGroup>) => {
+        this._assignedDistributionGroups = assignedGroups;
+      });
+    this.appState$.dispatch(distributionGroupActions.loadDistributionGroups());
+  }
+
   public loadGridFailureVersion(versionNumber: string): void {
     if (!!versionNumber && +versionNumber < this.maxVersionNumber) {
       this.appState$.dispatch(gridFailureActions.loadGridFailureVersion({ gridFailureId: this._gridFailureId, versionNumber: +versionNumber }));
@@ -252,22 +292,18 @@
     this._setGridFailureStations(versionNumber);
   }
 
-  public setGridFailureId(gridFailureId: string) {
-    this._gridFailureId = gridFailureId;
-  }
-
   public loadGridFailureDistributionGroups(gridFailureId: string): void {
     this.appState$.dispatch(gridFailureActions.loadGridFailureDistributionGroups({ payload: gridFailureId }));
   }
 
-  public loadDistributionGroups(): void {
-    this.appState$.dispatch(distributionGroupActions.loadDistributionGroups());
-  }
-
   public loadGridFailurePublicationChannels(gridFailureId: string): void {
     this.appState$.dispatch(gridFailureActions.loadGridFailurePublicationChannels({ payload: gridFailureId }));
   }
 
+  public setGridFailureId(gridFailureId: string) {
+    this._gridFailureId = gridFailureId;
+  }
+
   public setState(newState: string): void {
     this.gridFailureStates$
       .pipe(
@@ -401,29 +437,16 @@
     }
   }
 
-  public setLatLong(hsnr: string): void {
-    const test$ = this.actionsSubject.pipe(
-      ofType(gridFailureActions.loadAddressHouseNumbersSuccess),
-      map(action => action.payload),
-      takeUntil(this._endSubscriptions$)
-    );
-    if (!!this.addressHouseNumbers && this.addressHouseNumbers.length > 0) {
-      const failureHousenumber: models.FailureHousenumber = this.addressHouseNumbers.find((housenumber: models.FailureHousenumber) => {
-        return housenumber.housenumber === hsnr;
-      });
-      if (!!failureHousenumber) {
-        this.appState$.dispatch(gridFailureActions.loadGridFailureAddress({ payload: failureHousenumber.uuid }));
-      }
-    }
-    test$.pipe(take(1)).subscribe((addresses: Array<models.FailureHousenumber>) => {
-      let failureHousenumber: models.FailureHousenumber;
+  private _setLatLong(hsnr: string): void {
+    this._addressHouseNumbers$.pipe(take(1)).subscribe((addresses: Array<models.FailureHousenumber>) => {
+      let addressHouseNumber: models.FailureHousenumber;
       if (!!addresses && addresses.length > 0) {
-        failureHousenumber = addresses.find((housenumber: models.FailureHousenumber) => {
+        addressHouseNumber = addresses.find((housenumber: models.FailureHousenumber) => {
           return housenumber.housenumber === hsnr;
         });
       }
-      if (!!failureHousenumber) {
-        this.appState$.dispatch(gridFailureActions.loadGridFailureAddress({ payload: failureHousenumber.uuid }));
+      if (!!addressHouseNumber) {
+        this.appState$.dispatch(gridFailureActions.loadGridFailureAddress({ payload: addressHouseNumber.uuid }));
       }
     });
   }
@@ -436,45 +459,12 @@
         map(action => action.payload),
         takeUntil(this._endSubscriptions$)
       )
-      .subscribe(hnr => {
-        if (hnr.length > 0) {
-          hnr.sort(sortAlphaNum);
-          this.addressHouseNumbers = hnr;
+      .subscribe(houseNumbers => {
+        if (houseNumbers.length > 0) {
+          houseNumbers.sort(sortAlphaNum);
+          this._addressHouseNumbers$.next(houseNumbers);
         }
       });
-
-    this.gridFailureDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe((formState: FormGroupState<models.GridFailure>) => {
-      if (!formState.value || !formState.controls) return;
-
-      this.currentFormState = formState;
-      this._showButtonsByState(formState.value.statusIntern);
-      this._setDynamicRequired();
-      this._handleUserDefinedProperties(formState);
-    });
-
-    this.actionsSubject
-      .pipe(
-        ofType(gridFailureActions.loadGridFailureVersionsSuccess),
-        takeUntil(this._endSubscriptions$),
-        map(action => {
-          const gridFailures: models.GridFailure[] = action['payload'];
-          return !!gridFailures && Math.max(...gridFailures.map(o => o.versionNumber));
-        })
-      )
-      .subscribe(versionNumber => {
-        this.maxVersionNumber = versionNumber;
-      });
-
-    this.actionsSubject
-      .pipe(
-        ofType(gridFailureActions.loadStationsSuccess),
-        map(action => action.payload),
-        takeUntil(this._endSubscriptions$)
-      )
-      .subscribe((stations: Array<models.FailureStation>) => {
-        this._stations = stations;
-      });
-
     this.actionsSubject
       .pipe(
         ofType(gridFailureActions.loadGridFailureAddressSuccess),
@@ -487,45 +477,44 @@
         this.latLonMapping(event, false);
       });
 
-    this.gridFailurePolygon$.subscribe((polygon: Array<[number, number]>) => {
+    this.gridFailureDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe((formState: FormGroupState<models.GridFailure>) => {
+      if (!formState.value || !formState.controls) return;
+
+      this.currentFormState = formState;
+      this._showButtonsByState(formState.value.statusIntern);
+      this._setDynamicRequired();
+      this._handleUserDefinedProperties(formState);
+    });
+
+    this.gridFailurePolygon$.pipe(takeUntil(this._endSubscriptions$)).subscribe((polygon: Array<[number, number]>) => {
       this.currentFormState.value.addressPolygonPoints = !!polygon ? box(polygon) : null;
       this.currentGridFailureDetailsCoords = new models.FailureCoordsInformation(this.currentFormState.value);
     });
 
-    this.actionsSubject
-      .pipe(
-        ofType(gridFailureActions.loadGridFailureDistributionGroupsSuccess),
-        map(action => action.payload),
-        takeUntil(this._endSubscriptions$)
-      )
-      .subscribe((assignedGroups: Array<models.DistributionGroup>) => {
-        this._assignedDistributionGroups = assignedGroups;
-      });
-
     this.gridFailurePublicationChannels$.pipe(takeUntil(this._endSubscriptions$)).subscribe((channels: Array<models.PublicationChannel>) => {
       this.selectedPublicationChannels = channels.map(s => s.publicationChannel);
       this.disablePublishButton = channels.length > 0 && !channels.find(channel => !channel.published);
     });
 
-    this.gridFailureDetailsFormState$.subscribe(gridFailureDetails => {
-      let failureRadius: models.FailureRadius;
-      if (!!gridFailureDetails.value.radiusId) {
-        this.gridFailureRadii$.subscribe(radiusIds => {
+    combineLatest([this.gridFailureDetailsFormState$, this.gridFailureRadii$])
+      .pipe(takeUntil(this._endSubscriptions$))
+      .subscribe(([gridFailureDetails, radiusIds]) => {
+        let failureRadius: models.FailureRadius;
+        if (!!gridFailureDetails.value.radiusId) {
           if (radiusIds.length !== 0) {
             failureRadius = radiusIds.find(item => item.id === gridFailureDetails.value.radiusId);
             gridFailureDetails.value.radius = failureRadius.radius;
           }
-        });
-      }
+        }
 
-      if (
-        this.currentGridFailureDetailsCoords.latitude !== gridFailureDetails.value.latitude ||
-        this.currentGridFailureDetailsCoords.longitude !== gridFailureDetails.value.longitude ||
-        this.currentGridFailureDetailsCoords.radius !== gridFailureDetails.value.radius
-      ) {
-        this.currentGridFailureDetailsCoords = new models.FailureCoordsInformation(gridFailureDetails.value);
-      }
-    });
+        if (
+          this.currentGridFailureDetailsCoords.latitude !== gridFailureDetails.value.latitude ||
+          this.currentGridFailureDetailsCoords.longitude !== gridFailureDetails.value.longitude ||
+          this.currentGridFailureDetailsCoords.radius !== gridFailureDetails.value.radius
+        ) {
+          this.currentGridFailureDetailsCoords = new models.FailureCoordsInformation(gridFailureDetails.value);
+        }
+      });
   }
 
   public searchForStation = (text$: Observable<string>) =>
@@ -713,49 +702,6 @@
     this.appState$.dispatch(new DisableAction(INITIAL_STATE.controls.radiusId.id));
   }
 
-  private _disableStationControls(): void {
-    this.appState$.dispatch(new DisableAction(INITIAL_STATE.controls.stationDescription.id));
-  }
-
-  public loadInitialAddressData(formState: FormGroupState<models.GridFailure>) {
-    if (!formState.value || !formState.controls) return;
-
-    this.appState$.dispatch(
-      gridFailureActions.loadAllAddressCommunities({
-        branch: formState.value.branch,
-      })
-    );
-    this.appState$.dispatch(
-      gridFailureActions.loadAddressDistrictsOfCommunity({
-        branch: formState.value.branch,
-        community: formState.value.city,
-      })
-    );
-    this.appState$.dispatch(
-      gridFailureActions.loadAddressPostalcodes({
-        branch: formState.value.branch,
-        community: formState.value.city,
-        district: formState.value.district,
-      })
-    );
-    this.appState$.dispatch(
-      gridFailureActions.loadAddressStreets({
-        branch: formState.value.branch,
-        postcode: formState.value.postcode,
-        community: formState.value.city,
-        district: formState.value.district,
-      })
-    );
-    this.appState$.dispatch(
-      gridFailureActions.loadAddressHouseNumbers({
-        branch: formState.value.branch,
-        postcode: formState.value.postcode,
-        community: formState.value.city,
-        street: formState.value.street,
-      })
-    );
-  }
-
   public loadAddressPostalcodes(): void {
     const branch = !!this.currentFormState ? this.currentFormState.value.branch : null;
     const community = !!this.currentFormState ? this.currentFormState.value.city : null;
@@ -799,6 +745,49 @@
     this.appState$.dispatch(gridFailureActions.deleteDistributionGroupAssignment({ gridFailureId: this._gridFailureId, groupId: groupId }));
   }
 
+  private _disableStationControls(): void {
+    this.appState$.dispatch(new DisableAction(INITIAL_STATE.controls.stationDescription.id));
+  }
+
+  private _loadInitialAddressData(formState: FormGroupState<models.GridFailure>) {
+    if (!formState.value || !formState.controls) return;
+
+    this.appState$.dispatch(
+      gridFailureActions.loadAllAddressCommunities({
+        branch: formState.value.branch,
+      })
+    );
+    this.appState$.dispatch(
+      gridFailureActions.loadAddressDistrictsOfCommunity({
+        branch: formState.value.branch,
+        community: formState.value.city,
+      })
+    );
+    this.appState$.dispatch(
+      gridFailureActions.loadAddressPostalcodes({
+        branch: formState.value.branch,
+        community: formState.value.city,
+        district: formState.value.district,
+      })
+    );
+    this.appState$.dispatch(
+      gridFailureActions.loadAddressStreets({
+        branch: formState.value.branch,
+        postcode: formState.value.postcode,
+        community: formState.value.city,
+        district: formState.value.district,
+      })
+    );
+    this.appState$.dispatch(
+      gridFailureActions.loadAddressHouseNumbers({
+        branch: formState.value.branch,
+        postcode: formState.value.postcode,
+        community: formState.value.city,
+        street: formState.value.street,
+      })
+    );
+  }
+
   private _setBranchIds(): void {
     this.gridFailureBranches$.subscribe((branches: models.FailureBranch[]) => {
       this.branches = branches;
@@ -898,7 +887,7 @@
     switch (userDefinedProperty) {
       case formState.controls.__formBranch.id:
       case formState.id:
-        this.loadInitialAddressData(formState);
+        this._loadInitialAddressData(formState);
         break;
 
       case formState.controls.postcode.id:
@@ -924,7 +913,7 @@
         );
         break;
       case formState.controls.housenumber.id:
-        this.setLatLong(formState.controls.housenumber.value);
+        this._setLatLong(formState.controls.housenumber.value);
         break;
 
       default: