rxjs/operators#debounceTime JavaScript Examples
The following examples show how to use
rxjs/operators#debounceTime.
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: index.js From sampo-ui with MIT License | 6 votes |
fullTextSearchEpic = (action$, state$) => action$.pipe(
ofType(FETCH_FULL_TEXT_RESULTS),
withLatestFrom(state$),
debounceTime(500),
switchMap(([action, state]) => {
const requestUrl = `${apiUrl}/full-text-search?q=${action.query}`
return ajax.getJSON(requestUrl).pipe(
map(response => updateResults({
resultClass: 'fullTextSearch',
data: response.data,
sparqlQuery: response.sparqlQuery,
query: action.query,
jenaIndex: action.jenaIndex
})),
catchError(error => of({
type: FETCH_RESULTS_FAILED,
resultClass: 'fullTextSearch',
error: error,
message: {
text: backendErrorText,
title: 'Error'
}
}))
)
})
)
Example #2
Source File: index.js From sampo-ui with MIT License | 6 votes |
clientFSFetchResultsEpic = (action$, state$) => action$.pipe(
ofType(CLIENT_FS_FETCH_RESULTS),
withLatestFrom(state$),
debounceTime(500),
switchMap(([action, state]) => {
const { perspectiveID, jenaIndex } = action
const federatedSearchState = state[perspectiveID]
const selectedDatasets = pickSelectedDatasets(federatedSearchState.datasets)
const dsParams = selectedDatasets.map(ds => `dataset=${ds}`).join('&')
let requestUrl
if (action.jenaIndex === 'text') {
requestUrl = `${apiUrl}/federated-search?q=${action.query}&${dsParams}&perspectiveID=${perspectiveID}`
} else if (action.jenaIndex === 'spatial') {
const { latMin, longMin, latMax, longMax } = federatedSearchState.maps.boundingboxSearch
requestUrl = `${apiUrl}/federated-search?latMin=${latMin}&longMin=${longMin}&latMax=${latMax}&longMax=${longMax}&${dsParams}&perspectiveID=${perspectiveID}`
}
return ajax.getJSON(requestUrl).pipe(
map(response => clientFSUpdateResults({
results: response,
jenaIndex
})),
catchError(error => of({
type: CLIENT_FS_FETCH_RESULTS_FAILED,
error: error,
message: {
text: backendErrorText,
title: 'Error'
}
}))
)
})
)
Example #3
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 #4
Source File: exception-search.js From real-time-map with MIT License | 4 votes |
exceptionSearch = {
exceptionResultsCache: {},
displayList: {},
get searchInput() {
return document.getElementById("RTM-exception-search-bar");
},
init(mapPropsToComponent) {
// Init rxjs debounce search.
const searchInputObservable$ = fromEvent(exceptionSearch.searchInput, "input").pipe(map(i => i.currentTarget.value));
const debouncedInput = searchInputObservable$.pipe(debounceTime(250));
debouncedInput.subscribe((searchInput) => exceptionSearch.buildSearchList(searchInput, mapPropsToComponent));
},
loadSavedExceptionConfig(mapPropsToComponent) {
return getBlobStorage().then(val => {
if (val.length > 0 && !storage.setBlobStorageObj) { storage.setBlobStorageObj = val[0]; }
else {
return saveBlobStorage("Exception", {}).then(() => {
return getBlobStorage().then(val => {
storage.setBlobStorageObj = val[0];
});
});
};
exceptionSearch.searchInput.value = "";
const cachedExceptions = JSON.parse(val[0].data);
if (cachedExceptions.configData.Exception) {
exceptionSearch.displayList = cachedExceptions.configData.Exception;
storage.selectedExceptions = filterByVisibility(exceptionSearch.displayList);
exceptionSearch.buildExceptionDisplayList(mapPropsToComponent);
}
}).catch(error =>
console.warn("Server is unavailable, please try again later: ", error)
);
},
buildSearchList(searchInput, mapPropsToComponent) {
return getRulesByName(searchInput).then(ruleList => {
ruleList.forEach(rule => {
let {
color,
name,
id,
baseType
} = rule;
if (baseType === "Stock") { name += " (Default)"; };
const visible = true;
exceptionSearch.exceptionResultsCache[name] = { color, name, id, visible, baseType };
});
mapPropsToComponent(Object.values(exceptionSearch.exceptionResultsCache));
});
},
handleItemSelected(event, mapPropsToComponent) {
event.preventDefault();
exceptionSearch.saveSelectedValue(mapPropsToComponent);
},
saveSelectedValue(mapPropsToComponent) {
const { value } = exceptionSearch.searchInput;
const exceptionData = exceptionSearch.exceptionResultsCache[value];
if (exceptionData) {
exceptionSearch.displayList[exceptionData.id] = exceptionData;
exceptionSearch.saveConfig(mapPropsToComponent);
exceptionSearch.searchInput.value = "";
}
return exceptionData;
},
buildExceptionDisplayList(mapPropsToComponent) {
mapPropsToComponent(Object.values(exceptionSearch.displayList)
.filter(ruleData => ruleData.id && ruleData.name));
},
deleteItemFromExceptionList(id, mapPropsToComponent) {
delete exceptionSearch.displayList[id];
exceptionSearch.saveConfig(mapPropsToComponent);
},
saveConfig(mapPropsToComponent) {
storage.selectedExceptions = filterByVisibility(exceptionSearch.displayList);
storage.setBlobStorageObj ? setBlobStorage("Exception", exceptionSearch.displayList) : saveBlobStorage("Exception", exceptionSearch.displayList);
exceptionSearch.buildExceptionDisplayList(mapPropsToComponent);
storage.dateKeeper$.update();
},
toggleExceptionVisibility(ruleID, mapPropsToComponent) {
const selectedException = exceptionSearch.displayList[ruleID];
selectedException.visible = !selectedException.visible;
exceptionSearch.saveConfig(mapPropsToComponent);
},
deleteAllItems(mapPropsToComponent) {
exceptionSearch.displayList = {};
exceptionSearch.saveConfig(mapPropsToComponent);
},
setVisibilityForAllItems(visibility, mapPropsToComponent) {
Object.values(exceptionSearch.displayList)
.forEach(selectedItem =>
selectedItem.visible = visibility
);
exceptionSearch.saveConfig(mapPropsToComponent);
}
}
Example #5
Source File: status-search.js From real-time-map with MIT License | 4 votes |
diagnosticSearch = {
resultsCache: {},
displayList: {},
get searchInput() {
return document.getElementById("RTM-status-search-bar");
},
init(mapPropsToComponent) {
// Init rxjs debounce search.
const searchInputObservable$ = fromEvent(diagnosticSearch.searchInput, "input").pipe(map(i => i.currentTarget.value));
const debouncedInput = searchInputObservable$.pipe(debounceTime(250));
debouncedInput.subscribe((searchInput) => diagnosticSearch.buildSearchList(searchInput, mapPropsToComponent));
},
loadSavedStatusConfig(mapPropsToComponent) {
return getBlobStorage().then(val => {
if (val.length === 0) { return; }
const cachedDiagnostics = JSON.parse(val[0].data);
if (cachedDiagnostics.configData.Status) {
diagnosticSearch.displayList = cachedDiagnostics.configData.Status;
storage.selectedStatuses = filterByVisibility(diagnosticSearch.displayList);
diagnosticSearch.buildStatusDisplayList(mapPropsToComponent);
}
});
},
buildSearchList(searchInput, mapPropstoComponent) {
return getDiagnosticByName(searchInput).then(diagnosticResults => {
diagnosticResults.forEach(diagnostic => {
const {
id,
name,
unitOfMeasure
} = diagnostic;
const visible = true;
diagnosticSearch.resultsCache[name] = { name, id, visible, unitOfMeasure };
});
mapPropstoComponent(Object.values(diagnosticSearch.resultsCache));
});
},
handleItemSelected(event, mapPropsToComponent) {
event.preventDefault();
diagnosticSearch.saveSelectedValue(mapPropsToComponent);
},
saveSelectedValue(mapPropsToComponent) {
const { value } = diagnosticSearch.searchInput;
const diagnosticData = diagnosticSearch.resultsCache[value];
if (diagnosticData) {
diagnosticSearch.displayList[diagnosticData.id] = diagnosticData;
diagnosticSearch.searchInput.value = "";
diagnosticSearch.saveConfig(mapPropsToComponent);
}
return diagnosticData;
},
buildStatusDisplayList(mapPropsToComponent) {
mapPropsToComponent(Object.values(diagnosticSearch.displayList)
.filter(diagnostic => diagnostic.id && diagnostic.name));
},
deleteItemFromStatusList(id, mapPropsToComponent) {
delete diagnosticSearch.displayList[id];
diagnosticSearch.saveConfig(mapPropsToComponent);
},
saveConfig(mapPropsToComponent) {
storage.selectedStatuses = filterByVisibility(diagnosticSearch.displayList);
storage.setBlobStorageObj ? setBlobStorage("Status", diagnosticSearch.displayList) : saveBlobStorage("Status", diagnosticSearch.displayList);
storage.dateKeeper$.update();
diagnosticSearch.buildStatusDisplayList(mapPropsToComponent);
},
toggleStatusVisibility(id, mapPropsToComponent) {
const selectedDiagnostic = diagnosticSearch.displayList[id];
selectedDiagnostic.visible = !selectedDiagnostic.visible;
diagnosticSearch.saveConfig(mapPropsToComponent);
},
deleteAllItems(mapPropsToComponent) {
diagnosticSearch.displayList = {};
diagnosticSearch.saveConfig(mapPropsToComponent);
},
showAllItems(mapPropsToComponent) {
Object.values(diagnosticSearch.displayList)
.forEach(selectedDiagnostic =>
selectedDiagnostic.visible = true
);
diagnosticSearch.saveConfig(mapPropsToComponent);
},
hideAllItems(mapPropsToComponent) {
Object.values(diagnosticSearch.displayList)
.forEach(selectedDiagnostic =>
selectedDiagnostic.visible = false
);
diagnosticSearch.saveConfig(mapPropsToComponent);
}
}
Example #6
Source File: vehicle-search.js From real-time-map with MIT License | 4 votes |
deviceSearch = {
shown: true,
deviceResultsCache: {},
selectedIDS: {},
get searchInput() {
return document.getElementById("RTM-vehicle-search-bar");
},
init(mapPropsToComponent) {
// Init rxjs debounce search.
const searchInputObservable = fromEvent(deviceSearch.searchInput, "input").pipe(map(i => i.currentTarget.value));
const debouncedInput = searchInputObservable.pipe(debounceTime(250));
debouncedInput.subscribe((searchInput) => deviceSearch.buildSearchList(searchInput, mapPropsToComponent));
},
loadSavedDeviceConfig(mapPropsToComponent) {
return getBlobStorage().then(val => {
if (val.length === 0) { return; }
const cachedDevices = JSON.parse(val[0].data);
if (cachedDevices.configData.Vehicle) {
deviceSearch.selectedIDS = cachedDevices.configData.Vehicle;
deviceSearch.applyFilter();
deviceSearch.buildDeviceDisplayList(mapPropsToComponent);
}
});
},
buildSearchList(searchInput, mapPropsToComponent) {
const nameSearchMultiCall = [
createDeviceByNameCall(searchInput),
createGroupsByNameCall(searchInput)
];
return makeAPIMultiCall(nameSearchMultiCall).then(results => {
// deviceList = results[0];
results[0]
.map(deviceSearch.saveDeviceDataToCache);
// groupList = results[1];
results[1]
.map(deviceSearch.saveGroupDataToCache);
mapPropsToComponent(Object.values(deviceSearch.deviceResultsCache));
});
},
saveDeviceDataToCache(deviceData) {
const data = {};
["id", "name", "groups"].forEach(prop => data[prop] = deviceData[prop]);
data.visible = true;
deviceSearch.deviceResultsCache[data.name] = data;
return data;
},
saveGroupDataToCache(deviceData) {
const data = {};
["id", "name", "color"].forEach(prop => data[prop] = deviceData[prop]);
data.visible = true;
data.name += " (Group)";
deviceSearch.deviceResultsCache[data.name] = data;
return data;
},
buildDeviceDisplayList(mapPropsToComponent) {
deviceSearch.mapPropsToComponent = mapPropsToComponent;
mapPropsToComponent(Object.values(deviceSearch.selectedIDS)
.filter(device => device.id && device.name));
},
handleItemSelected(event, mapPropsToComponent) {
event.preventDefault();
deviceSearch.saveSelectedValue(mapPropsToComponent);
},
saveSelectedValue(mapPropsToComponent) {
const { value } = deviceSearch.searchInput;
if (!deviceSearch.deviceResultsCache.hasOwnProperty(value)) {
return;
}
const deviceData = deviceSearch.deviceResultsCache[value];
deviceData.visible = true;
const {
id,
name,
groups,
color,
visible
} = deviceData;
if (color) { //It's a group
deviceSearch.selectedIDS[id] = { id, name, color, visible };
}
else {
deviceSearch.selectedIDS[id] = { id, name, groups, visible };
}
deviceSearch.searchInput.value = "";
deviceSearch.saveConfig(mapPropsToComponent);
return deviceData;
},
deleteItemFromdeviceList(id, mapPropsToComponent) {
delete deviceSearch.selectedIDS[id];
deviceSearch.saveConfig(mapPropsToComponent);
},
deleteAllItems(mapPropsToComponent) {
deviceSearch.selectedIDS = {};
deviceSearch.saveConfig(mapPropsToComponent);
},
saveConfig(mapPropsToComponent) {
storage.setBlobStorageObj ? setBlobStorage("Vehicle", deviceSearch.selectedIDS) : saveBlobStorage("Vehicle", deviceSearch.selectedIDS);
deviceSearch.applyFilter();
deviceSearch.buildDeviceDisplayList(mapPropsToComponent);
},
applyFilter() {
_getDeviceList(deviceSearch.selectedIDS).then(() => {
_applyDeviceFilter(Object.keys(storage.selectedDevices));
});
},
showAll(mapPropsToComponent) {
Object.values(deviceSearch.selectedIDS)
.forEach(selectedDevice =>
selectedDevice.visible = true
);
deviceSearch.saveConfig(mapPropsToComponent);
},
hideAll(mapPropsToComponent) {
Object.values(deviceSearch.selectedIDS)
.forEach(selectedDevice =>
selectedDevice.visible = false
);
deviceSearch.saveConfig(mapPropsToComponent);
},
toggleDeviceVisibility(id, mapPropsToComponent) {
const selectedDevice = deviceSearch.selectedIDS[id];
selectedDevice.visible = !selectedDevice.visible;
deviceSearch.saveConfig(mapPropsToComponent);
},
zoomIntoDevice(id) {
const deviceMarker = markerList[id];
if (deviceMarker) {
const newZoomLevel = Math.max(Math.min(storage.map.getZoom() + 1, 18), 15);
storage.map.flyTo(deviceMarker.currentlatLng, newZoomLevel);
} else {
alert("Sorry, no current day data for selected vehicle.");
}
}
}