rxjs/operators#scan TypeScript Examples

The following examples show how to use rxjs/operators#scan. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: product.service.ts    From Angular-ActionStreams with MIT License 6 votes vote down vote up
// Current page
  // Emitting 0 reinitializes the page count
  currentPage$ = this.pageNumberSubject
    .pipe(
      scan((acc, one) => {
        if (one === 0) {
          return 1;
        }
        else {
          return acc + one;
        }
      })
    );
Example #2
Source File: index.ts    From dbm with Apache License 2.0 6 votes vote down vote up
manifest$ = merge(
  ...Object.entries({
    "**/*.scss": stylesheets$,
    "**/*.ts*":  javascripts$
  })
    .map(([pattern, observable$]) => (
      defer(() => process.argv.includes("--watch")
        ? watch(pattern, { cwd: "src" })
        : EMPTY
      )
        .pipe(
          startWith("*"),
          switchMapTo(observable$.pipe(toArray()))
        )
    ))
)
  .pipe(
    scan((prev, mapping) => (
      mapping.reduce((next, [key, value]) => (
        next.set(key, value.replace(`${base}/`, ""))
      ), prev)
    ), new Map<string, string>()),
  )
Example #3
Source File: auth.state.ts    From auth0-angular with MIT License 6 votes vote down vote up
/**
   * Trigger used to pull User information from the Auth0Client.
   * Triggers when the access token has changed.
   */
  private accessTokenTrigger$ = this.accessToken$.pipe(
    scan(
      (
        acc: { current: string | null; previous: string | null },
        current: string | null
      ) => {
        return {
          previous: acc.current,
          current,
        };
      },
      { current: null, previous: null }
    ),
    filter(({ previous, current }) => previous !== current)
  );
Example #4
Source File: customOperators.ts    From webapp with MIT License 6 votes vote down vote up
rankPriority =
  () =>
  <T>(source: Observable<RankItem<T>>) =>
    source.pipe(
      scan(
        (lastEmitted, value) => {
          const betterPriority =
            !lastEmitted.emittedOnce ||
            value.priority < lastEmitted.lastPriority;

          return betterPriority
            ? {
                emit: true,
                emittedOnce: true,
                lastPriority: value.priority,
                toEmit: value.data
              }
            : {
                emit: false,
                emittedOnce: true,
                lastPriority: lastEmitted.lastPriority,
                toEmit: undefined
              };
        },
        {
          emit: false,
          emittedOnce: false,
          lastPriority: 0,
          toEmit: undefined
        } as {
          emit: boolean;
          emittedOnce: boolean;
          lastPriority: number;
          toEmit: undefined | T;
        }
      ),
      filter(emission => emission.emit),
      pluck("toEmit")
    ) as Observable<T>
Example #5
Source File: customOperators.ts    From webapp with MIT License 6 votes vote down vote up
distinctArrayItem =
  <T>(initialValue: T[], comparator?: (a: T, b: T) => boolean) =>
  (source: Observable<T[]>) =>
    source.pipe(
      scan(
        (acc, item) => {
          const difference = differenceWith(
            item,
            acc.allEmissions,
            comparator || isEqual
          );
          return {
            allEmissions: [...acc.allEmissions, ...difference],
            newData: difference
          };
        },
        { allEmissions: initialValue, newData: [] } as DataCache<T>
      ),
      filter(dataCache => dataCache.newData.length > 0),
      pluck("newData"),
      startWith(initialValue)
    )
Example #6
Source File: dyn-control.class.ts    From open-source with MIT License 6 votes vote down vote up
ngOnInit(): void {
    super.ngOnInit();

    // merge any configured paramFns
    if (this.config.paramFns) {
      this.updateParams(undefined, this.config.paramFns);
    }

    // listen parameters changes after the control is ready
    combineLatest([
      isObservable(this.config.params) ? this.config.params : of(this.config.params || {}),
      this.node.paramsUpdates$.pipe(startWith({})),
    ]).pipe(
      scan<any>((params, [config, updates]) => merge(true, params, config, updates)),
      filter(params => !Array.isArray(params)), // filters the first scan
    ).subscribe((params) => {
      // emulates ngOnChanges
      const change = new SimpleChange(this.params, this.completeParams(params), !this.params);
      this.params$.next(change.currentValue);
      this._logger.nodeParamsUpdated(this.node, this.constructor.name, this.params);

      setTimeout(() => {
        // emulates ngOnChanges and async pipe
        this.ngOnChanges({ params: change });
        this.node.markParamsAsLoaded();
        this._ref.markForCheck();
      }, 1);
    });
  }
Example #7
Source File: download.ts    From ngx-operators with MIT License 6 votes vote down vote up
export function download(
  saver?: (b: Blob) => void
): (source: Observable<HttpEvent<Blob>>) => Observable<Download> {
  return (source: Observable<HttpEvent<Blob>>) =>
    source.pipe(
      scan(
        (last: Download, event): Download => {
          if (isHttpProgressEvent(event)) {
            return {
              progress: event.total
                ? Math.round((100 * event.loaded) / event.total)
                : last.progress,
              state: "IN_PROGRESS",
              content: null
            };
          }
          if (isHttpResponse(event)) {
            if (saver && event.body) {
              saver(event.body);
            }
            return {
              progress: 100,
              state: "DONE",
              content: event.body
            };
          }
          return last;
        },
        { state: "PENDING", progress: 0, content: null }
      ),
      distinctUntilChanged(
        (a, b) =>
          a.state === b.state &&
          a.progress === b.progress &&
          a.content === b.content
      )
    );
}
Example #8
Source File: upload.ts    From ngx-operators with MIT License 6 votes vote down vote up
export function upload(): (
  source: Observable<HttpEvent<unknown>>
) => Observable<Upload> {
  const initialState: Upload = { state: "PENDING", progress: 0 };
  const reduceState = (state: Upload, event: HttpEvent<unknown>): Upload => {
    if (isHttpProgressEvent(event)) {
      return {
        progress: event.total
          ? Math.round((100 * event.loaded) / event.total)
          : state.progress,
        state: "IN_PROGRESS",
      };
    }
    if (isHttpResponse(event)) {
      return {
        progress: 100,
        state: "DONE",
      };
    }
    return state;
  };
  return (source) =>
    source.pipe(
      scan(reduceState, initialState),
      distinctUntilChanged(
        (a, b) => a.state === b.state && a.progress === b.progress
      )
    );
}
Example #9
Source File: team-advance.page.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
ionViewWillEnter() {
    this.tasksService.getTotalTaskCount().subscribe((totalTaskCount) => (this.totalTaskCount = totalTaskCount));

    this.setupDefaultFilters();
    this.currentPageNumber = 1;
    this.isLoading = true;

    this.teamAdvancerequests$ = this.loadData$.pipe(
      concatMap(({ pageNumber, state, sortParam, sortDir }) =>
        this.advanceRequestService.getTeamAdvanceRequests({
          offset: (pageNumber - 1) * 10,
          limit: 10,
          queryParams: {
            ...this.getExtraParams(state),
          },
          filter: {
            state,
            sortParam,
            sortDir,
          },
        })
      ),
      map((res) => res.data),
      scan((acc, curr) => {
        if (this.currentPageNumber === 1) {
          return curr;
        }
        return acc.concat(curr);
      }, [] as ExtendedAdvanceRequest[]),
      shareReplay(1),
      finalize(() => (this.isLoading = false))
    );

    this.count$ = this.loadData$.pipe(
      switchMap(({ state, sortParam, sortDir }) =>
        this.advanceRequestService.getTeamAdvanceRequestsCount(
          {
            ...this.getExtraParams(state),
          },
          {
            state,
            sortParam,
            sortDir,
          }
        )
      ),
      shareReplay(1),
      finalize(() => (this.isLoading = false))
    );

    this.isInfiniteScrollRequired$ = this.teamAdvancerequests$.pipe(
      concatMap((teamAdvancerequests) =>
        this.count$.pipe(
          take(1),
          map((count) => count > teamAdvancerequests.length)
        )
      )
    );

    this.loadData$.subscribe(noop);
    this.teamAdvancerequests$.subscribe(noop);
    this.count$.subscribe(noop);
    this.isInfiniteScrollRequired$.subscribe(noop);
    this.loadData$.next({
      pageNumber: this.currentPageNumber,
      state: this.filters.state || [],
      sortParam: this.filters.sortParam,
      sortDir: this.filters.sortDir,
    });

    this.getAndUpdateProjectName();
  }
Example #10
Source File: select.ts    From ble with Apache License 2.0 5 votes vote down vote up
entityMove: Epic = (action$, { store }) => {
	return action$.pipe (
		ofType('entityPointerDown'),
		filter(() => store.editor.mode === EditorMode.select),
		// middle click is panning only
		filter(({ ev }) => !(ev.data.pointerType === 'mouse' && ev.data.button === 1)),
		// it's important to use global and not original event
		// because TouchEvents don't have clientX
		pluck('ev', 'data', 'global'),
		// we copy the relevant data because react pools events
		map(({ x, y }) => ({
			x: x + store.editor.renderZone.x,
			y: y + store.editor.renderZone.y,
		})),
		tap(() => {
			store.undoManager.startGroup();
		}),
		switchMap(({ x, y }) => fromEvent<PointerEvent>(document, 'pointermove').pipe(
			map(({ clientX, clientY }) => new Vector(clientX, clientY)),
			startWith(new Vector(x, y)),
			pairwise(),
			map(([prev, curr]) => curr.clone().sub(prev)),
			filter((vec) => vec.len2() !== 0),
			map((vec) => vec.scale(1/store.editor.scale)),
			scan((acc, delta) => {
				const totalDelta = acc.clone().add(delta);

				const displacement = snapBoxToGrid(
					new Box(
						store.editor.selectionAsAabb.pos.clone().add(totalDelta),
						store.editor.selectionAsAabb.w,
						store.editor.selectionAsAabb.h,
					),
					store.editor.gridCellSize,
				);

				store.editor.selection.forEach((entity: IEntity) => {
					entity.params.move(totalDelta.x + displacement.x, totalDelta.y + displacement.y);
				});

				return displacement.reverse();
			}, new Vector(0, 0)),
			takeUntil(fromEvent(document, 'pointerup').pipe(
				tap(() => {
					store.undoManager.stopGroup();
				}),
			)),
		)),
		ignoreElements(),
	);
}
Example #11
Source File: index.ts    From open-source with MIT License 5 votes vote down vote up
function waitForAll(): OperatorFunction<string, string[]> {
  return (source$: Observable<string>) => source$.pipe(
    scan<string, string[]>((all, file) => all.concat(file), []),
    last(), // wait until all files are processed
    filter(all => Boolean(all.length)), // prevents EmptyError
  );
  // use concatMap(files => from(files)) to re-emit the files one by one
}
Example #12
Source File: index.ts    From open-source with MIT License 5 votes vote down vote up
function waitForAll(): OperatorFunction<string, string[]> {
  return (source$: Observable<string>) => source$.pipe(
    scan<string, string[]>((all, file) => all.concat(file), []),
    last(), // wait until all files are processed
    filter(all => Boolean(all.length)), // prevents EmptyError
  );
  // use concatMap(files => from(files)) to re-emit the files one by one
}
Example #13
Source File: with-history.ts    From s-libs with MIT License 5 votes vote down vote up
export function withHistory<T>(count: number): OperatorFunction<T, T[]> {
  return scan<T, T[]>((buf, value) => [value, ...buf.slice(0, count)], []);
}