Получение неопределенного не является функцией одной из функций

Я новичок в React Native. Я пытаюсь сделать текстовое поле автозаполнения в React Native. Я использую плагин response-native-autocomplete-input. Я читаю данные из файла JSON. Я все время получаю эту ошибку. Пользователь вводит имя службы в текстовое поле, чтобы они могли ввести ser, и он покажет service1 в качестве опции для выбора пользователем.

введите здесь описание изображения

Ниже мой код App.js:

 /**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */



import service from './services.json';


import Autocomplete from 'react-native-autocomplete-input';
import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  TouchableOpacity,
  View
} from 'react-native';



class Autocomp extends Component {
  static renderServices(coservice) {
    const { ser, Location, secondLoc} = coservice;


    return (
      <View>
        <Text style={styles.titleText}>{ser}</Text>
        <Text style={styles.openingText}>{secondLoc}</Text>
      </View>
    );
  }

  constructor(props) {
    super(props);
    this.state = {
       query: '',
       services:[]
    };
  }

  componentDidMount(){
      const {results: services} = service;
      this.setState({services});

  }

  findServices(query) {
    if (query === '') {
      return [];
    }

    const {services } = this.state;
    const regex = new RegExp(`${query.trim()}`, 'i');
    return services.filter(coservice=> coservice.ser.search(regex) >= 0);
  }

  render() {
    const { query } = this.state;
    const services = this.findservices(query);
    const comp = (a, b) => a.toLowerCase().trim() === b.toLowerCase().trim();

    return (
      <View style={styles.container}>
        <Autocomplete
          autoCapitalize="none"
          autoCorrect={false}
          containerStyle={styles.autocompleteContainer}
          data={services.length === 1 && comp(query, services[0].ser) ? [] : services}
          defaultValue={query}
          onChangeText={text => this.setState({ query: text })}
          placeholder="Enter Services here"
          renderItem={({ ser, Phone }) => (
            <TouchableOpacity onPress={() => this.setState({ query: ser })}>
              <Text style={styles.itemText}>
                {ser} 
              </Text>
            </TouchableOpacity>
          )}
        />
        <View style={styles.descriptionContainer}>
          {services.length > 0 ? (
            Autocomp.renderServices(services[0])
          ) : (
            <Text style={styles.infoText}>
              Enter services
            </Text>
          )}
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#F5FCFF',
    flex: 1,
    paddingTop: 25
  },
  autocompleteContainer: {
    flex: 1,
    left: 0,
    position: 'absolute',
    right: 0,
    top: 0,
    zIndex: 1
  },
  itemText: {
    fontSize: 15,
    margin: 2
  },
  descriptionContainer: {
    // `backgroundColor` needs to be set otherwise the
    // autocomplete input will disappear on text input.
    backgroundColor: '#F5FCFF',
    marginTop: 25
  },
  infoText: {
    textAlign: 'center'
  },
  titleText: {
    fontSize: 18,
    fontWeight: '500',
    marginBottom: 10,
    marginTop: 10,
    textAlign: 'center'
  },
  directorText: {
    color: 'grey',
    fontSize: 12,
    marginBottom: 10,
    textAlign: 'center'
  },
  openingText: {
    textAlign: 'center'
  }
});

export default Autocomp;

ниже мой файл JSON (services.json):

  {
    "id":1,
    "ser": "Service1",
    "Location": "TestLoc1",
    "Phone":"(999)-921-9292",
    "SecondLoc": "TestLoc",
    "email":"[email protected]",
    "sourceLat":"33.977806",
    "sourceLong":"-117.373261",
    "destLatL1":"33.613355",
    "destLongL1":"-114.596569",
    "destLatL2":"33.761693",
    "destLongL2":"-116.971169",
    "destAddr1": "Test Drive, 99999",
    "destAddr2": "Test City, Test Drive, 92345"
  },

  {
    "id":1,
    "ser": "TestService",
    "Location": "TestLoc1",
    "Phone":"(999)-921-9292",
    "SecondLoc": "TestLoc",
    "email":"[email protected]",
    "sourceLat":"33.977806",
    "sourceLong":"-117.373261",
    "destLatL1":"33.613355",
    "destLongL1":"-114.596569",
    "destLatL2":"33.761693",
    "destLongL2":"-116.971169",
    "destAddr1": "Test Drive, 99999",
    "destAddr2": "Test City, Test Drive, 92345"
  },
  ]

Любая помощь будет принята с благодарностью.


person Anjali    schedule 26.04.2018    source источник


Ответы (2)


Это просто глупая ошибка, имена ваших функций не совпадают. Вы позвонили findservices, но это должно быть findServices с заглавными буквами S

Также я хочу отметить, что ваш способ поиска предложений хорош, но в нем есть ошибка. В вашей функции findServices у вас есть

const regex = new RegExp(`${query.trim()}`, 'i');

Вы создаете новое регулярное выражение из query, но это не всегда удается. Например, если пользователь вводит специальный символ, такой как [, эта строка кода выдаст ошибку, потому что query теперь содержит открытую скобку, но не закрывающую скобку ], поэтому регулярное выражение не может быть построено из query. Вы должны изменить его примерно так:

findServices(query) {
    const inputValue = query.trim().toLowerCase();
    const inputLength = inputValue.length;

    const { services } = this.state;
    return inputLength === 0 ? [] : services.filter(ser =>
        ser.toLowerCase().slice(0, inputLength) === inputValue);
}
person K.Wu    schedule 26.04.2018

В дополнение к ответу K.Wu удалите эту строку const services = this.findservices(query); в методе рендеринга и поместите ее в onChangeText автозаполнения. Он должен срабатывать после того, как пользователь ввел текст в поле автозаполнения, не отображаемое по умолчанию.

Autocomplete
          autoCapitalize="none"
          autoCorrect={false}
          containerStyle={styles.autocompleteContainer}
          data={services.length === 1 && comp(query, services[0].ser) ? [] : services}
          defaultValue={query}
          onChangeText={text => this.findServices(text}
          placeholder="Enter Services here"
          renderItem={({ ser, Phone }) => (
            <TouchableOpacity onPress={() => this.setState({ query: ser })}>
              <Text style={styles.itemText}>
                {ser} 
              </Text>
            </TouchableOpacity>
          )}
        />
person digit    schedule 26.04.2018
comment
Как только я удалил const services = this.findservices (query); Я получаю сообщение об ошибке: не могу найти службы переменных - person Anjali; 27.04.2018