Need guidance / explicit example on how to incorporate createConnector

Hi, I have decided to use Algolia to build out the world’s first crowdsourcing site for scientific controversies. It’s a very exciting project about 5 or 6 years in the making now, and based upon my dozen years embedded with a group of against-the-mainstream theorists struggling to be heard out.

I have truly enjoyed working with your product up to this point. The documentation has been brilliant and the React components have just worked

… that is, at least until it came time to implement this higher-order component (HOC). I spent a few hours last night struggling with an obscure React/Webpack error message. This message leaves me with no idea of how to proceed.

My use case for needing to use createConnector() is that I am getting a flash of incorrect search result content when the results from hitting the first character return. This is because I have already set up the Algolia / React Router integration, which exposed searchState for me. When I use this.state.searchState to conditionally display <Hits />, there is a bit of a time gap between this query change and the results change. And I assume that this is what is creating the flash of incorrect search result.

If the site is working, you should be able to observe this behavior by just typing a search into the search box at controversiesofscience.com.

What is hurting me here is that there are no complete examples – seemingly on the entire Internet – for how to hook up these createConnector() HOC’s. If I could just see a complete example for how this works, I’d be off to the races in a few seconds.

All I have are the snippets here …

… the problem being that the connections are half the battle. I really can’t tell from this snippet if I am connecting createConnector() properly.

My expected behavior is that when there is no search, there should be no search results and no search query parameters visible. It should be a very simple search box with an icon when somebody lands on the page.

Here is the component for that homepage …

Oops, not sure why it cut my code out. But, here it is:

// React Dependencies
import React, { Component } from 'react';

// UI Dependencies
import './Home.css';
import elephant from '../../images/elephant.png';
import { Grid } from 'react-bootstrap';

// Algolia Search / React Router Integration Dependencies
import { InstantSearch, Hits, SearchBox, Stats, Pagination } from 'react-instantsearch/dom';
import SearchResult from '../SearchResult/SearchResult';
import qs from 'qs';
import { withRouter } from 'react-router-dom';
// import content from './ConditionalContentConnector';

// Permits HTML markup encoding in feed text
// import { Parser as HtmlToReactParser } from 'html-to-react';

// React Router / Algolia Search integration
const
	updateAfter = 700,
	createURL = state => `?${qs.stringify(state)}`,
	searchStateToUrl = (props, searchState) =>
		searchState ? `${props.location.pathname}${createURL(searchState)}` : '';

class HomeComponent extends Component {
	constructor(props) {
		super(props);

		this.state = {
			searchState: qs.parse(props.location.search.slice(1))
		};

		this.props = props;
	}

	// This and the other InstantSearch / React Router integration code comes from
	// https://github.com/algolia/react-instantsearch/blob/master/packages
	// /react-instantsearch/examples/react-router/src/App.js 
	onSearchStateChange = searchState => {
		clearTimeout(this.debouncedSetState);
		this.debouncedSetState = setTimeout(() => {

			// This was not in the supplied code, but it is necessary in order to
			// clear out the search query parameter when there is no active search
			if (!searchState.query) {
				searchState = {};
			}

			this.props.history.push(
				searchStateToUrl(this.props, searchState),
				searchState
			);
		}, updateAfter);

		this.setState({ searchState });
	};

	render() {
		// Do not do this: It's way too slow ...
		// const isSearch = this.props.router.location && this.props.router.location.search ? 
		// 	this.props.router.location.state.query !== '' :
		// 	false;

		return (
			<div className="Home">

				<img
					alt="blind men and the elephant logo"
					src={elephant}
					className="Logo" />

				<InstantSearch
					appId="HDX7ZDMWE9"
					apiKey="f9898dbf6ec456d206e59bcbc604419d"
					indexName="controversy_cards"
					searchState={this.state.searchState}
					onSearchStateChange={this.onSearchStateChange.bind(this)}
					createURL={createURL}>

					<Grid>

						<SearchBox
							className="SearchBox"
							translations={{placeholder: 'Enter a Controversy'}} />

						{ this.state.searchState.query && <Stats /> }
						{ this.state.searchState.query && <Hits hitComponent={SearchResult} /> }

					</Grid>

					{ this.state.searchState.query && <Pagination showLast /> }

				</InstantSearch>

			</div>
		);
	}
}

export default withRouter(HomeComponent);

Hi @paradigmsareconstruc!

If I understood correctly, what you want to do is hiding the results of the empty query. Is it correct?

If that’s so you can use the createConnector as a conditional display like describe in this guide => https://community.algolia.com/react-instantsearch/guide/Conditional_display.html

Here’s a codesandbox illustrating it. I used our dataset as yours doesn’t have the same structure between results for the empty query and the other one.

Edit algolia/react-instantsearch: react-router

Thanks for taking the time to code that up! It looks exactly like what I was looking for, and I’ll try to work these suggestions into my code tonight.

That example shows the connections (at least for me) in a much clearer way than the existing docs; you guys might want to consider appending it to the content at the conditional display URL (?).

Just tried it out, and this works perfectly. Many thanks!

Indeed there’s some development with are considering regarding of what you’re doing:

  • add an option to skip the first query
  • add a new API to simplify the conditional display