I'm new to React. I'm building a web application that starts off with a search function. The users of my app are meant to start by searching for a company, selecting the one they want, and then the app should display some of the information we have on that company to them: name, domain name, city, region (State), and maybe short_description.
I've got an async search that populates options from the company name from my Firebase Firestore collection but once the company is selected, my component is not displaying the other information.
Here's my code:
import React, { Component } from "react";
import AsyncSelect from "react-select/async";
import { defaultTheme } from "react-select";
import Button from "@atlaskit/button";
import firebase from "./../util/firebase";
const { colors } = defaultTheme;
const selectStyles = {
control: (provided) => ({ ...provided, minWidth: 240, margin: 8 }),
menu: () => ({ boxShadow: "inset 0 1px 0 rgba(0, 0, 0, 0.1)" })
};
const db = firebase.firestore();
class DashSearch extends Component {
state = { isOpen: false, value: undefined };
toggleOpen = () => {
this.setState((state) => ({ isOpen: !state.isOpen }));
};
onSelectChange = (value) => {
this.toggleOpen();
this.setState({ value });
};
constructor(props) {
super(props);
this.state = {
results: []
};
this.search = this.search.bind(this);
}
search(results) {
this.setState({ results });
}
getInfo = (search) => {
db.collection("organizations")
.where("name", "===", search)
.then(({ data }) => {
this.setState({ results: data.data });
});
};
loadOptions = async (search) => {
search = search.toLowerCase().replace(/\W/g, "");
return new Promise((resolve) => {
db.collection("orgs")
.where("keywords", "array-contains", search)
.get()
.then((docs) => {
if (!docs.empty) {
let results = [];
docs.forEach(function (doc) {
const company = {
value: doc.data().uuid,
label: doc.data().name,
domain: doc.data().domain,
region: doc.data().region,
city: doc.data().city
};
results.push(company);
});
return resolve(results);
} else {
return resolve([]);
}
});
});
};
handleOnChange = () => {
this.setState(
{
search: this.search.value
},
() => {
if (this.state.search && this.state.search.length > 1) {
if (this.state.search.length % 2 === 0) {
this.getInfo();
}
} else if (!this.state.search) {
}
}
);
};
render() {
const { isOpen, value } = this.state;
return (
<div className="mt-4 mb-40">
<Dropdown
isOpen={isOpen}
onClose={this.toggleOpen}
target={
<Button
iconAfter={<ChevronDown />}
onClick={this.toggleOpen}
isSelected={isOpen}
>
{value ? `Company: ${value.label}` : "Select a Company"}
</Button>
}
>
<AsyncSelect
autoFocus
backspaceRemovesValue={true}
components={{ DropdownIndicator, IndicatorSeparator: null }}
controlShouldRenderValue={true}
hideSelectedOptions={false}
menuIsOpen
placeholder="Search..."
styles={selectStyles}
tabSelectsValue={false}
value={this.search.value}
isClearable
isSearchable
loadOptions={this.loadOptions}
onChange={this.handleOnChange}
/>
</Dropdown>
<div>
<p>{this.state.results}</p>
</div>
</div>
);
}
}
const Menu = (props) => {
const shadow = "hsla(218, 50%, 10%, 0.1)";
return (
<div
css={{
backgroundColor: "white",
borderRadius: 4,
boxShadow: `0 0 0 1px ${shadow}, 0 4px 11px ${shadow}`,
marginTop: 8,
position: "absolute",
zIndex: 2
}}
{...props}
/>
);
};
const Blanket = (props) => (
<div
css={{
bottom: 0,
left: 0,
top: 0,
right: 0,
position: "fixed",
zIndex: 1
}}
{...props}
/>
);
const Dropdown = ({ children, isOpen, target, onClose }) => (
<div css={{ position: "relative" }}>
{target}
{isOpen ? <Menu>{children}</Menu> : null}
{isOpen ? <Blanket onClick={onClose} /> : null}
</div>
);
const Svg = (p) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
focusable="false"
role="presentation"
{...p}
/>
);
const DropdownIndicator = () => (
<div css={{ color: colors.neutral20, height: 24, width: 32 }}>
<Svg>
<path
d="M16.436 15.085l3.94 4.01a1 1 0 0 1-1.425 1.402l-3.938-4.006a7.5 7.5 0 1 1 1.423-1.406zM10.5 16a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11z"
fill="currentColor"
fillRule="evenodd"
/>
</Svg>
</div>
);
const ChevronDown = () => (
<Svg style={{ marginRight: -6 }}>
<path
d="M8.292 10.293a1.009 1.009 0 0 0 0 1.419l2.939 2.965c.218.215.5.322.779.322s.556-.107.769-.322l2.93-2.955a1.01 1.01 0 0 0 0-1.419.987.987 0 0 0-1.406 0l-2.298 2.317-2.307-2.327a.99.99 0 0 0-1.406 0z"
fill="currentColor"
fillRule="evenodd"
/>
</Svg>
);
export default DashSearch;
And this is what it looks like:
