react-nativealgoliainstantsearchreact-instantsearch

How to prevent initial load from Algolia instant search in react native?


I have a users collection which I want to query as the user types, but when I switch to the Search Users Screen, all the users have populated on the screen even the search is empty.

How can I prevent this and only send the results to the client when he/she types in the search box??

I found some other links and resources but either they were too old, difficult to understand for me or using React instead of React Native.

I am a beginner developer and if you would be elaborate with the solution then that would be great.

This is my code:

SEARCH_USER.JS:

import React, {Component} from 'react';
import {
  View,
  Text,
  TextInput,
  Alert,
  FlatList,
  ActivityIndicator,
} from 'react-native';


import firestore from '@react-native-firebase/firestore';
import algoliasearch from 'algoliasearch';
import {
  InstantSearch,
  connectSearchBox,
  connectInfiniteHits,
} from 'react-instantsearch-native';
import PropTypes from 'prop-types';
import InfiniteHits from '../components/Algolia Components/InfiniteHits';



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

    this.state = {
      loading: false,
      value: null,
    };
  }


  searchClient = algoliasearch(
    '########',
    '####################',
  );

  render() {
    return (
      <View>
        <SecondaryHeader secondaryHeaderTitle="Add Buddies" />
        <InstantSearch
          searchClient={this.searchClient}
          indexName="prod_USERSCOLLECTION"
          onSearchStateChange={searchState =>
            console.log('=====> ', searchState)
          }>
          <ConnectedSearchBox />
          <InfiniteHits navigation={this.props.navigation} />
        </InstantSearch>
      </View>
    );
  }
}

class SearchBox extends Component {
  render() {
    console.log('Connected Search Box called');
    return (
      <View
        style={[
          textInput.generalTextInput,
          {
            marginBottom: 24,
            alignSelf: 'center',
            justifyContent: 'center',
          },
        ]}>
        <TextInput
          placeholderTextColor="#333647"
          style={[textInput.generalTextInput, {alignSelf: 'center'}]}
          onChangeText={text => this.props.refine(text)}
          value={this.props.currentRefinement}
          placeholder={'Search'}
          clearButtonMode={'always'}
          spellCheck={false}
          autoCorrect={false}
          autoCapitalize={'none'}
        />
      </View>
    );
  }
}

SearchBox.propTypes = {
  refine: PropTypes.func.isRequired,
  currentRefinement: PropTypes.string,
};

const ConnectedSearchBox = connectSearchBox(SearchBox);
export default SearchUserScreen;

InfiniteHits.js:

import React, {Component} from 'react';
import {StyleSheet, Text, View, FlatList} from 'react-native';
import {connectInfiniteHits} from 'react-instantsearch-native';
import AddFriendComponent from '../AddFriend';

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

    this.navigation = this.props.navigation;
  }
  _renderItem = ({item}) => {
    return (
      <AddFriendComponent
        username={item.username}
        fullName={item.fullName}
        onPressUserProfile={() =>
          this.props.navigation.navigate('UserProfile', {profileId: item.uid})
        }
      />
    );
  };

  render() {
    return (
      <FlatList
        data={this.props.hits}
        keyExtractor={item => item.objectID}
        // ItemSeparatorComponent={() => <View style={styles.separator} />}
        onEndReached={() => this.props.hasMore && this.props.refine()}
        renderItem={this._renderItem}
      />
    );
  }
}
export default connectInfiniteHits(InfiniteHits);

Solution

  • After reading through more material I found this https://www.algolia.com/doc/guides/building-search-ui/going-further/conditional-requests/react/

    And made the following changes to my code and it succeeded.

    
    conditionalQuery = {
        search(requests) {
          if (
            requests.every(({params}) => !params.query) ||
            requests.every(({params}) => params.query === ' ') ||
            requests.every(({params}) => params.query === '  ') ||
            requests.every(({params}) => params.query === '   ')
          ) {
            // Here we have to do something else
            console.log('Empty Query');
            return Promise.resolve({
              results: requests.map(() => ({
                hits: [],
                nbHits: 0,
                nbPages: 0,
                processingTimeMS: 0,
              })),
            });
          }
          const searchClient = algoliasearch(
            '########',
            '###################',
          );
          return searchClient.search(requests);
        },
      };
      render() {
        return (
          <View>
            <SecondaryHeader secondaryHeaderTitle="Add Buddies" />
            <InstantSearch
              searchClient={this.conditionalQuery}
              indexName="prod_USERSCOLLECTION"
              onSearchStateChange={searchState =>
                console.log('=====> ', searchState)
              }>
              <ConnectedSearchBox />
              <InfiniteHits navigation={this.props.navigation} />
            </InstantSearch>
          </View>
        );
      }
    
    

    This solution can still be improved for the spaces typed, but I don't know how to do that.