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 |
updates$ = new Subject()
Example #2
Source File: alert.service.js From maps with MIT License | 5 votes |
alertSubject = new Subject()
Example #3
Source File: alert.service.js From next-js-10-crud-example with MIT License | 5 votes |
alertSubject = new Subject()
Example #4
Source File: alert.service.js From react-alert-notifications with MIT License | 5 votes |
alertSubject = new Subject()
Example #5
Source File: alert.service.js From react-formik-master-details-crud-example with MIT License | 5 votes |
alertSubject = new Subject()
Example #6
Source File: alert.service.js From react-hooks-bootstrap-alerts with MIT License | 5 votes |
alertSubject = new Subject()
Example #7
Source File: alert.service.js From react-signup-verification-boilerplate with MIT License | 5 votes |
alertSubject = new Subject()
Example #8
Source File: service.js From react-orgchart with MIT License | 5 votes |
subject1 = new Subject()
Example #9
Source File: service.js From react-orgchart with MIT License | 5 votes |
subject2 = new Subject()
Example #10
Source File: SearchPage.js From app with MIT License | 4 votes |
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} –{' '}
{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 '{item}' 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 |
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);
}
}