0

I'm developing a React native application. I'm using the React native elements library.

I'm using the Search bar. But when I type faster than the keyboard, the search is not working properly.

Example;

I'm writing "Jack," but it's called "Ja".

I hope I can explain my problem. Because my English is not very good. Thanks in advance for your help.

handleRefresh = () => {
    this.setState({
      offset: 0,
      maxSize: 10,
      isSearch: false
    }, () => {
        this.loadData();
    });
};

handleLoadMore = () => {
    this.setState({
        maxSize: this.state.maxSize + 10            
    }, () => {
        this.loadData();
    });
};    

loadData = async () => {
    try {
        const { username, token, offset, maxSize } = this.state;

        var credentials = Base64.btoa(username + ':' + token);
        var URL         = `https://crm.example.com/api/v1/Lead?select=name,status&sortBy=createdAt&asc=false&offset=${offset}&maxSize=${maxSize}`;            

        await axios.get(URL, {headers : { 'Espo-Authorization' : credentials }})
        .then(this.dataSuccess.bind(this))
        .catch(this.dataFail.bind(this));
    }catch (error) {
        Alert.alert(
            'Hata',
            'Bir hata meydana geldi. Lütfen yöneticiye başvurunuz.',
            [
                { text: 'Tamam', onPress: () => null }
            ]
        );
    }
};

searchLead = async (text) => {
    try {
        if(text) {
            this.setState({ searchText: text, isSearch: true, isLoading: true });

            const { username, token, maxSize } = this.state;

            var credentials = Base64.btoa(username + ':' + token);
            var URL = "https://crm.example.com/api/v1/Lead?select=name,status&sortBy=createdAt&asc=false&where[0][type]=textFilter&where[0][value]=" + text;

            await axios.get(URL, { headers : { 'Espo-Authorization' : credentials }})
            .then(this.dataSearch.bind(this))
            .catch(this.dataFail.bind(this));
        }else {
            this.setState({ searchText: '' });
            this.handleRefresh();
        }            
    }catch (error) {
        Alert.alert(
            'Hata',
            'Arama başarısız oldu. Lütfen yöneticiniz ile görüşün.',
            [
                { text: 'Tamam', onPress: () => null }
            ]
        );
    }
}

dataSuccess(response) {
    this.setState({ isLoading: false, leadList: response.data.list });
}

dataSearch(response) {
    this.setState({ isLoading: false, searchData: response.data.list });
}

dataFail(error) {
    this.setState({ isLoading: false });

    Alert.alert(
        'Hata',
        'Beklenmedik bir hata oluştu',
        [
            { text: 'Tamam', onPress: () => null }
        ]
    );
}

render() {
    const { isLoading, isRefreshing, searchText, isSearch, leadList, searchData } = this.state;
    return(
        <View style={styles.container}>
            <SearchBar 
                placeholder="Bir lead arayın..."
                searchIcon={<Icon
                    name="search"
                    color="white"
                    size={21}
                />}
                onChangeText={this.searchLead.bind(this)}
                onClear={this.handleRefresh.bind(this)}
                onCancel={this.handleRefresh.bind(this)}
                value={searchText}
            />
            { isLoading ? <ActivityIndicator style={styles.loading} size="large" color="orange" /> :
                isSearch ?
                    <ScrollView>
                        <FlatList
                            data={searchData}
                            showLoading={true}
                            renderItem={({item}) =>
                                <ListItem                                    
                                    title={item.name}
                                    subtitle={item.status}
                                    bottomDivider={true}
                                />
                            }
                            keyExtractor={this.keyExtractor}
                            refreshing={isRefreshing}
                            onRefresh={this.handleRefresh}
                        />
                    </ScrollView> :                            
                    <FlatList
                        data={leadList}
                        renderItem={({item}) =>
                            <ListItem                                
                                title={item.name}
                                subtitle={item.status}
                                bottomDivider={true}
                            />
                        }
                        keyExtractor={this.keyExtractor}
                        refreshing={isRefreshing}
                        onRefresh={this.handleRefresh}
                        onEndReached={this.handleLoadMore}
                        onEndReachedThreshold={0.2}
                    />                            
            }
        </View>
    )
}
}
Gündoğdu Yakıcı
  • 677
  • 2
  • 10
  • 31

1 Answers1

0

Let me start by saying I don't know reactjs very well, but I think this may work (there may be far better solutions though)

searchLead = (() => {
    let req;
    const delayedRequest = callback => {
        const timeout = setTimeout(callback, 500);
        return {
            cancel() {
                clearTimeout(timeout);
            }
        };
    };
    return (text) => {
        req && req.cancel();
        req = delayedRequest(async () => {
            try {
                if(text) {
                    this.setState({ searchText: text, isSearch: true, isLoading: true });

                    const { username, token, maxSize } = this.state;

                    var credentials = Base64.btoa(username + ':' + token);
                    var URL = "https://crm.example.com/api/v1/Lead?select=name,status&sortBy=createdAt&asc=false&where[0][type]=textFilter&where[0][value]=" + text;

                    await axios.get(URL, { headers : { 'Espo-Authorization' : credentials }})
                    .then(this.dataSearch.bind(this))
                    .catch(this.dataFail.bind(this));
                } else {
                    this.setState({ searchText: '' });
                    this.handleRefresh();
                }            
            }catch (error) {
                Alert.alert(
                    'Hata',
                    'Arama başarısız oldu. Lütfen yöneticiniz ile görüşün.',
                    [
                        { text: 'Tamam', onPress: () => null }
                    ]
                );
            }
        });
    };
})();
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Thanks, I have tried, but it is not considered as a function. – Gündoğdu Yakıcı Mar 28 '19 at 13:03
  • really? how so? it's an IIFE that returns a function, therefore `searchLead` should be a function - are you sure? What is the error message you are getting? nevermind - I found my fault ... hanf on @Dodiş – Jaromanda X Mar 28 '19 at 13:06
  • Now try it - I forgot to move the `async` @Dodiş – Jaromanda X Mar 28 '19 at 13:08
  • No function does not recognize. The color of the function name is different. – Gündoğdu Yakıcı Mar 28 '19 at 13:45
  • sorry, are you getting an error, or are you just basing your comments on the colour of an element in an editor? if you're getting an error, please tell me the error, in full, not just "function does not recognize" - as this is not something a browser or whatever reactjs does would say - there'd be something that makes sense – Jaromanda X Mar 28 '19 at 13:47
  • Here's the problem **your code** isn't valid anyway - you've omitted something, so babel, with react enabled, chokes on **your code** – Jaromanda X Mar 28 '19 at 13:54