rxjs#Subject JavaScript Examples

The following examples show how to use rxjs#Subject. 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: identity-manager.js    From payroll-app with GNU Affero General Public License v3.0 5 votes vote down vote up
updates$ = new Subject()
Example #2
Source File: alert.service.js    From maps with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #3
Source File: alert.service.js    From next-js-10-crud-example with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #4
Source File: alert.service.js    From react-alert-notifications with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #5
Source File: alert.service.js    From react-formik-master-details-crud-example with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #6
Source File: alert.service.js    From react-hooks-bootstrap-alerts with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #7
Source File: alert.service.js    From react-signup-verification-boilerplate with MIT License 5 votes vote down vote up
alertSubject = new Subject()
Example #8
Source File: service.js    From react-orgchart with MIT License 5 votes vote down vote up
subject1 = new Subject()
Example #9
Source File: service.js    From react-orgchart with MIT License 5 votes vote down vote up
subject2 = new Subject()
Example #10
Source File: SearchPage.js    From app with MIT License 4 votes vote down vote up
function SearchPage() {
  const classes = useStyles();
  const { showError } = useNotifications();

  // State
  const [showAddressPicker, setShowAddressPicker] = useState(false);
  const [nearbyRequests, setNearbyRequests] = useState(null);
  const [currentLatLong, setCurrentLatLong] = useState({
    latitude: DEFAULT_LATITUDE,
    longitude: DEFAULT_LONGITUDE,
  });
  const [currentPlaceLabel, setCurrentPlaceLabel] = React.useState(
    `Using default location: ${DEFAULT_LOCATION_NAME}`,
  );
  const [distance, setDistance] = useState(defaultDistance);
  const [searching, setSearching] = useState(false);

  const [onSearch$] = useState(() => new Subject());

  // Data
  const user = useUser();
  const firestore = useFirestore();
  const analytics = useAnalytics();
  const { GeoPoint } = useFirestore;

  async function searchForNearbyRequests({ searchLocation, searchDistance }) {
    if (!searchLocation) return;
    // Use lat/long set to state (either from profile or default)
    const { latitude, longitude } = searchLocation;
    setSearching(true);
    analytics.logEvent('search', {
      search_term: `latitude=${latitude}&longitude=${longitude}`,
    });
    try {
      // Query for nearby requests
      const geofirestore = new GeoFirestore(firestore);
      const nearbyRequestsSnap = await geofirestore
        .collection(REQUESTS_PUBLIC_COLLECTION)
        .near({
          center: new GeoPoint(latitude, longitude),
          radius: KM_TO_MILES * searchDistance,
        })
        .where('status', '==', 1)
        .limit(30)
        .get();
      const sortedByDistance = nearbyRequestsSnap.docs.sort(
        (a, b) => a.distance - b.distance,
      );
      setNearbyRequests(
        sortedByDistance.map((docSnap) => ({
          ...docSnap.data(),
          id: docSnap.id,
          distance: kmToMiles(docSnap.distance).toFixed(2),
        })),
      );
      setSearching(false);
    } catch (err) {
      showError('Error searching for nearby requests');
      // eslint-disable-next-line no-console
      console.log(err);
      setSearching(false);
    }
  }

  // Setup an observable for debouncing the search requests.
  useEffect(() => {
    const subscription = onSearch$
      .pipe(debounceTime(500))
      .subscribe(searchForNearbyRequests);

    return () => subscription.unsubscribe();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // This pushes new empty values to the observable when the distance or location changes.
  useEffect(() => {
    onSearch$.next({
      searchLocation: currentLatLong,
      searchDistance: distance,
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentLatLong, distance]);

  useEffect(() => {
    async function loadLatLongFromProfile() {
      // TODO: Search is triggered twice when the user is logged in. Once with the first render,
      //       and then again when the user is assigned.  Need to fix this behavior.
      // Set lat/long from profile or fallback to defaults
      if (user && user.uid) {
        const profileRef = firestore.doc(`${USERS_COLLECTION}/${user.uid}`);
        const profileSnap = await profileRef.get();
        const geopoint = profileSnap.get('preciseLocation');
        if (geopoint) {
          const userLocation = {
            latitude: geopoint.latitude,
            longitude: geopoint.longitude,
          };
          setCurrentLatLong(userLocation);
          setCurrentPlaceLabel(
            `Near ${profileSnap.get('generalLocationName')}`,
          );
          onSearch$.next({
            searchLocation: userLocation,
            searchDistance: defaultDistance,
          });
        } else {
          onSearch$.next({
            searchLocation: currentLatLong,
            searchDistance: defaultDistance,
          });
        }
      } else {
        onSearch$.next({
          searchLocation: currentLatLong,
          searchDistance: defaultDistance,
        });
      }
    }
    // NOTE: useEffect is used to load data so it can be done conditionally based
    // on whether current user is logged in
    loadLatLongFromProfile();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user]);

  function handleCopyNeedLink(id) {
    const el = document.createElement('textarea');
    document.body.appendChild(el);
    el.value = `${window.location.origin}${generatePath(REQUEST_PATH, {
      requestId: id,
    })}`;
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
  }

  // Gets the lat/lng for the selected address.
  function handlePlaceSelect(_event, selection) {
    if (!selection) return;
    geocodeByAddress(selection.description)
      .then((results) => getLatLng(results[0]))
      .then((latLng) => {
        setCurrentLatLong({ latitude: latLng.lat, longitude: latLng.lng });
      })
      .catch((error) => {
        showError('Failed to get the location from address.');
        // eslint-disable-next-line no-console
        console.error('Error', error);
      });
  }

  function handlePlaceChange(address) {
    setCurrentPlaceLabel(address);
  }

  return (
    <Container maxWidth="md">
      <Helmet>
        <title>Find Opportunities</title>
      </Helmet>
      <Typography variant="h6">Search Criteria</Typography>
      <Paper className={classes.filterPaper}>
        {!showAddressPicker && (
          <div className={classes.searchLocation}>
            <Typography id="continuous-slider">{currentPlaceLabel}</Typography>
            <Button
              data-test="new-location-button"
              onClick={() => setShowAddressPicker(true)}
              className={classes.enterAddressButton}>
              Select new location
            </Button>
          </div>
        )}
        {showAddressPicker && (
          <>
            <LoadScript
              id="script-loader"
              libraries={USED_GOOGLE_MAPS_LIBRARIES}
              googleMapsApiKey={process.env.REACT_APP_FIREBASE_API_KEY}>
              <PlacesAutocomplete
                value={currentPlaceLabel}
                onChange={handlePlaceChange}>
                {({ getInputProps, suggestions, loading }) => (
                  <>
                    {/* {console.log(suggestions)} */}
                    <Autocomplete
                      data-test="places-autocomplete"
                      onChange={handlePlaceSelect}
                      options={suggestions}
                      loading={loading}
                      getOptionLabel={(sug) => sug.description}
                      noOptionsText="No matches"
                      renderInput={(params) => (
                        <TextField
                          margin="none"
                          data-test="address-entry"
                          {...getInputProps({
                            ...params,
                            label: 'Address',
                            className: classes.searchInput,
                          })}
                          InputProps={{
                            ...params.InputProps,
                            endAdornment: (
                              <>
                                {loading && (
                                  <CircularProgress color="inherit" size={20} />
                                )}
                              </>
                            ),
                          }}
                        />
                      )}
                    />
                  </>
                )}
              </PlacesAutocomplete>
            </LoadScript>
            <Typography align="right" variant="caption" display="block">
              Powered by Google Maps
            </Typography>
          </>
        )}

        <Divider className={classes.divider} />

        <Typography id="continuous-slider" gutterBottom>
          Distance (in miles)
        </Typography>
        <div className={classes.distance}>
          <Slider
            defaultValue={defaultDistance}
            valueLabelDisplay="on"
            // valueLabelFormat={x => `${x} mi`}
            marks={markValues}
            onChange={(_event, value) => setDistance(value)}
            min={1}
            max={markValues[markValues.length - 1].value}
          />
        </div>
      </Paper>
      {searching && (
        <Paper className={classes.simplePaper}>
          <LinearProgress />
        </Paper>
      )}
      {nearbyRequests && nearbyRequests.length === 0 && (
        <Paper className={classes.simplePaper}>
          <Typography data-test="no-requests-found">
            No requests found with {distance} miles. You can try expanding the
            search area or try entering a new location.
          </Typography>
        </Paper>
      )}
      {nearbyRequests &&
        nearbyRequests.map((result) => (
          <Paper className={classes.resultPaper} key={result.id}>
            <Grid container>
              <Hidden xsDown>
                <Grid item className={classes.distanceContainer} sm={2}>
                  {result.distance}
                  <br />
                  miles
                </Grid>
              </Hidden>
              <Grid item className={classes.requestSummary} xs={12} sm={10}>
                {parseInt(result.immediacy, 10) > 5 && (
                  <img
                    align="right"
                    src="/taskIcon.png"
                    width="50px"
                    height="50px"
                    alt="Urgent"
                    title="Urgent"
                  />
                )}

                <Typography variant="h6">
                  {result.name ? result.name : result.firstName} &ndash;{' '}
                  {result.generalLocationName}
                </Typography>

                <Typography variant="caption" gutterBottom>
                  Requested {format(result.createdAt.toDate(), 'p - PPPP')}
                </Typography>

                <Typography variant="h5" className={classes.needs} gutterBottom>
                  {result.needs.map((item) => (
                    <React.Fragment key={item}>
                      {allCategoryMap[item] ? (
                        <Chip
                          size="small"
                          variant="outlined"
                          icon={
                            item === 'grocery-pickup' ? <GroceryIcon /> : null
                          }
                          label={allCategoryMap[item].shortDescription}
                        />
                      ) : (
                        <Alert severity="error">
                          Could not find &apos;{item}&apos; in all category map.
                        </Alert>
                      )}
                    </React.Fragment>
                  ))}
                  {result.needFinancialAssistance && (
                    <Chip
                      variant="outlined"
                      size="small"
                      icon={<FinancialAssitanceIcon />}
                      label="Need financial assistance"
                    />
                  )}
                </Typography>

                <Hidden smUp>
                  <Typography
                    align="right"
                    variant="h5"
                    className={classes.TaskTitle}>
                    {result.distance} miles
                  </Typography>
                </Hidden>

                <Grid container justify="flex-end">
                  <Grid item>
                    {navigator.share ? (
                      <Button
                        size="small"
                        onClick={() => {
                          navigator.share({
                            title: 'CV19 Assist Need Link',
                            text: 'CV19 Assist Need Link',
                            url: `${window.location.origin}${generatePath(
                              REQUEST_PATH,
                              {
                                requestId: result.id,
                              },
                            )}`,
                          });
                        }}>
                        SHARE
                      </Button>
                    ) : (
                      <Button
                        size="small"
                        onClick={() => handleCopyNeedLink(result.id)}>
                        COPY LINK FOR SHARING
                      </Button>
                    )}{' '}
                    <Button
                      component={Link}
                      to={generatePath(REQUEST_PATH, {
                        requestId: result.id,
                      })}
                      size="small"
                      color="primary"
                      disableElevation>
                      DETAILS...
                    </Button>
                  </Grid>
                </Grid>
              </Grid>
            </Grid>
          </Paper>
        ))}
    </Container>
  );
}
Example #11
Source File: date-keeper.js    From real-time-map with MIT License 4 votes vote down vote up
dateKeeper = {

  init(startDate, period = 1000) {

    this.startDate = startDate;
    this.newTime = startDate;
    this.period = period;
    this.paused = false;

    this.emitterSubject = new Subject();
    this.inputThrottler = new Subject();

    this.currentSecond$ = this.createDateKeeper();
    this.createInputThrottler();

    this.subscriberList = [];
  },

  get state() {
    // console.trace(new Date(this.newTime));
    return {
      period: this.period,
      newTimeSet: this.newTime,
      pause: this.paused
    };
  },

  get observable() {
    return this.currentSecond$;
  },

  getPeriod() {
    return this.period;
  },

  createDateKeeper() {
    const res = this.emitterSubject.pipe(

      startWith(this.state),

      switchMap(next => {

        if (next.pause) {
          return empty();
        }

        const res = interval(next.period).pipe(mapTo(false));
        if (next.newTimeSet) {
          this.newTime = false;
          return res.pipe(startWith(next.newTimeSet));
        }
        return res;

      }),

      scan((currentTime, newTimeSet) =>
        newTimeSet ? newTimeSet : currentTime + 1000,
        0
      ),

      publish()
    );

    res.connect();
    this.newTime = false;
    return res;
  },

  createInputThrottler() {

    this.inputThrottler.pipe(
      throttleTime(360)
    ).subscribe(state => {
      this.emitterSubject.next(state);
    });

  },

  emitNext() {
    this.inputThrottler.next(this.state);
  },

  subscribe(callback) {
    const newSub = this.currentSecond$.subscribe(callback);
    this.subscriberList.push(newSub);
    return newSub;
  },

  pause() {
    this.paused = true;
    this.emitNext();
  },

  resume() {
    this.paused = false;
    this.emitNext();
  },

  setPeriod(period) {
    this.period = period;
    this.paused = false;
    updatePeriodChangeFunctions(period);
    this.emitNext();
  },

  setNewTime(newTimeInput) {

    this.newTime = Math.round(newTimeInput / 1000) * 1000;

    if (this.newTime < storage.dayStart.getTime() || this.newTime > storage.dayEnd.getTime()) {
      this.pause();
      differentDateSet(this.newTime);
    }

    if (checkIfLive(this.newTime) > 600) {
      this.newTime = getLiveTime();
    }

    storage.currentTime = this.newTime;
    updateTimeChangeFunctions(this.newTime);

    this.paused = false;
    this.emitNext();
    resetTransitionAnimation();
  },

  update() {

    storage.currentTime += 1000;

    if (checkIfLive(storage.currentTime) > 600) {
      storage.currentTime = getLiveTime();
    }

    this.setNewTime(storage.currentTime);
  }

}