ngOnInit()

in web/frontend/src/app/pages/order-book/order-book-page/order-book-page.component.ts [75:269]


  ngOnInit() {
    this.initForm();
    this.activatedRoute.params.pipe(takeUntil(this.destroy$)).subscribe(() => {
      this.orderBookFiltersReady = false;
    });
    
    this.orientation$ = this.tabStorageService
      .getData()
      .pipe(map((data) => data?.orientation || EOrientations.price));
    
    this.hiddenExchanges$ = this.getActiveTab().pipe(
      switchMap(() => this.tabStorageService.getData(['hiddenExchanges'])),
      map((data) => data?.hiddenExchanges || []),
    );
    
    const storageData$ = this.getActiveTab().pipe(
      switchMap((tab) =>
        this.tabStorageService.getData().pipe(map((data) => ({data, tab: tab.tab}))),
      ),
      map(({data, tab}) => ({
        ...data,
        streams: data?.streams || (tab.stream ? [tab.stream] : null),
        symbol: data?.symbol || (tab?.symbol ? [tab.symbol] : null),
      })),
      distinctUntilChanged(equal),
      shareReplay(1),
    );

    this.exchanges$ = storageData$.pipe(
      map((data) => {
        if (!data?.symbol?.length) {
          return null;
        }
        
        return data?.exchanges ? this.sortByName(data?.exchanges) : null;
      }),
      distinctUntilChanged(equal),
    );
    
    let patching = false;
    const patchFilters = (callback) => {
      patching = true;
      callback();
      patching = false;
    };
    
    combineLatest([this.exchanges$.pipe(filter((e) => !!e)), this.hiddenExchanges$])
      .pipe(takeUntil(this.destroy$))
      .subscribe(([exchanges, hiddenExchanges]) => {
        patchFilters(() =>
          this.filters.get('exchanges').patchValue(
            exchanges.filter((e) => !hiddenExchanges.includes(e)),
            {emitEvent: false},
          ));
      });
    
    storageData$.pipe(takeUntil(this.destroy$)).subscribe((data) => {
      patchFilters(() =>
        this.filters.patchValue({
          streams: data?.streams || [],
          symbol: data?.symbol || [],
        }),
      );
    });
    
    storageData$
      .pipe(
        take(1),
        switchMap(() => this.filters.valueChanges.pipe(startWith(this.filters.value))),
        distinctUntilChanged(equal),
        pairwise(),
        filter(() => !patching),
        takeUntil(this.destroy$),
      )
      .subscribe(([prev, current]) => {
        const freshExchanges =
          (prev.symbol[0] && prev.symbol[0] !== current.symbol[0]) ||
          (prev.streams && JSON.stringify(prev.streams) !== JSON.stringify(current.streams));
        
        this.updateTab();
        
        this.tabStorageService.updateDataSync((data) => ({
          ...data,
          streams: current.streams,
          symbol: current.symbol,
          hiddenExchanges: freshExchanges ? [] : data?.hiddenExchanges,
          exchanges: freshExchanges ? null : data?.exchanges,
        }));
      });
    
    this.streams$ = this.streamsUpdated$.pipe(
      switchMap(() => this.streamsService.getList(true)),
      map((streams) =>
        streams
          .filter((s) => !!s.chartType?.find((ct) => ct.chartType === ChartTypes.PRICES_L2))
          .map(({key, name}) => ( { key, name } ))
      ),
    );

    this.streamNames$ = this.streams$.pipe(map((s) => s.map(str => str.name)));
    
    this.symbols$ = this.streams$.pipe(
      tap(streams => this.streams = streams),
      switchMap(() => storageData$),
      switchMap((data) => {
        if (!data?.streams?.length) {
          return of([]);
        }
        return combineLatest(
          data.streams.map((streamName: string) => {
            const stream = this.streams.find(streamItem => streamItem.name === streamName);

            return this.symbolsService.getSymbols(stream.key).pipe(
              catchError((e: HttpErrorResponse) => {
                if (e.status === 400 && e.error.message.startsWith('Unknown stream')) {
                  this.streamsUpdated$.next();
                  this.filters.get('streams').patchValue(data.streams.filter((s) => s !== stream));
                }
                
                return of([]);
              })
            )
          }),
        );
      }),
      map((responses) => {
        const unique = new Set<string>();
        responses.forEach((symbols) => symbols.forEach((symbol) => unique.add(symbol)));
        return [...unique].sort((a, b) => (a > b ? 1 : -1));
      }),
      shareReplay(1),
    );
    
    this.symbols$.pipe(takeUntil(this.destroy$)).subscribe((symbols) => {
      const chosen = this.filters.get('symbol').value[0];
      if (chosen && !symbols.includes(chosen)) {
        this.filters.get('symbol').patchValue([]);
      }
    });
    
    storageData$
      .pipe(
        tap((data) => {
          this.orderBookFiltersReady = !!(
            data?.symbol?.length &&
            data?.streams?.length &&
            (data.exchanges?.length !== data.hiddenExchanges?.length ||
              !data.hiddenExchanges?.length)
          );
        }),
        map((data) => ({...data, orientation: null, exchanges: null})),
        distinctUntilChanged(equal),
        takeUntil(this.destroy$),
        switchMap(() => {
          this.loading = true;
          this.noData = false;
          this.cdRef.detectChanges();
          return timer(5000);
        }),
      )
      .subscribe(() => {
        if (this.loading) {
          this.loading = false;
          this.noData = true;
        }
        
        this.cdRef.detectChanges();
      });
    
    this.bookState$.pipe(debounceTime(300), takeUntil(this.destroy$)).subscribe((state) => {
      this.loading = !state;
      this.noData = false;
      this.cdRef.detectChanges();
    });
    
    this.streamUpdatesService
      .onUpdates()
      .pipe(takeUntil(this.destroy$))
      .subscribe((update) => {
        if (update.renamed.length) {
          const selectedStreams = this.streams
            .filter(stream => this.filters.get('streams').value.includes(stream.name)).map(stream => stream.key);
          const streams = selectedStreams ? [...selectedStreams] : [];
          update.renamed.forEach(({oldName, newName}) => {
            const index = streams.findIndex((s) => s === oldName);
            if (index > -1) {
              streams.splice(index, 1, newName);
            }
          });
          this.filters.get('streams').patchValue(streams);
          this.streamsUpdated$.next();
          this.cdRef.detectChanges();
        }
      });
  }