Skip to content

Instantly share code, notes, and snippets.

@mdboop
Last active September 4, 2019 15:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdboop/ef7b19a63a281c3b4eddee2b90c7e0a2 to your computer and use it in GitHub Desktop.
Save mdboop/ef7b19a63a281c3b4eddee2b90c7e0a2 to your computer and use it in GitHub Desktop.
Simple Rxjs + Downshift autocomplete
import React from 'react';
import Downshift from 'downshift';
import Rx from 'rxjs';
import { ajax } from 'rxjs/observable/dom/ajax';
const makeUrl = search =>
`https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=${encodeURIComponent(str)}`;
const input$ = new Rx.Subject();
const search$ = input$
.debounceTime(400)
.distinctUntilChanged()
.filter(input => input.length > 1)
.switchMap(input =>
ajax({ url: makeUrl(input), method: 'GET', crossDomain: true })
.filter(results => !!results)
.map(({ response }) => response.query.search || [])
);
export default class extends React.Component {
constructor(props) {
super(props);
this.state = { results: [] };
}
componentDidMount() {
this.unsubscribe = search$.subscribe(
results => { this.setState({ results }); },
console.log,
);
}
componentWillUnMount() {
this.unsubscribe();
}
handleChange = e => {
input$.next(e.target.value);
};
render() {
return (
<Downshift
itemToString={(i) => i.title}
onChange={this.props.onChange}
render={({
getInputProps,
getItemProps,
getLabelProps,
isOpen,
inputValue,
highlightedIndex,
selectedItem,
}) => (
<div className="autocomplete-container">
<label {...getLabelProps()}>Search: </label>
<input {...getInputProps({ onChange: this.handleChange })} />
{isOpen ? (
<div>
{this.state.results
.map((item, index) => (
<div
{...getItemProps({
key: item.pageid,
index,
item,
style: {
backgroundColor:
highlightedIndex === index ? 'lightgray' : 'white',
fontWeight: selectedItem === item ? 'bold' : 'normal',
},
})}
>
{item.title}
</div>
))}
</div>
) : null}
</div>
)}
/>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment