Реагировать |Ошибка типа Promise Uncaught на Promise.then () - PullRequest
1 голос
/ 14 марта 2019

У меня есть следующий метод в React, который проверяет, присутствует ли имя пользователя в params.data в списке пользователей. Если пользователь присутствует, мы визуализируем обычное представление деталей. Если нет, мы показываем страницу 404.

  validateUsername = (match, params) =>
    listUsers().then(({ data }) => {
      if (Array.isArray(data.username).contains(params.username)) {
        return true;
      }
      return false;
    });

Это работает. Это работает ложь, обаяние, меня перенаправляют в правильном рендере каждый раз. Но я получаю эту ошибку, которую пытаюсь устранить, поскольку я планирую протестировать этот сценарий.

Вот компонент:

import { getUser, listUsers } from '../../config/service';
// The above are the services I use to call specific endpoint,
// They return a promise themselves.

class UserDetailsScreen extends Component {
  static propTypes = {
    match: PropTypes.shape({
      isExact: PropTypes.bool,
      params: PropTypes.object,
      path: PropTypes.string,
      url: PropTypes.string
    }),
    label: PropTypes.string,
    actualValue: PropTypes.string,
    callBack: PropTypes.func
  };

  state = {
    user: {}
  };

  componentDidMount() {
    this.fetchUser();
  }

  getUserUsername = () => {
    const { match } = this.props;
    const { params } = match; // If I print this, it is fine.
    return params.username;
  };

  fetchUser = () => {
    getUser(this.getUserUsername()).then(username => {
      this.setState({
        user: username.data
      });
    });
  };

  validateUsername = (params) =>
    listUsers().then(({ data }) => {
      // Data are printed, just fine. I get
      // the list of users I have on my API.
      if (Array.isArray(data.username).contains(params.username)) {
      // The error is here in params.username. It is undefined.
        return true;
      }
      return false;
    });

  renderNoResourceComponent = () => {
    const { user } = this.state;
    return (
      <div className="center-block" data-test="no-resource-component">
        <NoResource
           ... More content for the no user with that name render
        </NoResource>
      </div>
    );
  };

  render() {
    const { user } = this.state;
    const { callBack, actualValue, label } = this.props;
    return (
      <div className="container-fluid">
        {user && this.validateUsername() ? (
          <Fragment>
            <div className="row">
              ...More content for the normal render here...
            </div>
          </Fragment>
        ) : (
            <div className="container-fluid">
              {this.renderNoResourceComponent()}
            </div>
          )}
      </div>
    );
  }
}

export default UserDetailsScreen;

Не уверен, что не так, может быть, когда я звоню, данных нет, и мне нужно async-await или что-то в этом роде. Мне нужна помощь. Спасибо!

1 Ответ

0 голосов
/ 14 марта 2019
  1. Как уже упоминалось в комментариях Array.isArray() возвращается как логическое значение, и вы не можете вызывать методы массива для логических значений, вам нужно проверить, является ли data.username массивом, а затем запустить методы для него отдельно.

  2. Я также думаю, что вы должны использовать включает вместо contains

  3. Для обработки ошибок, возникающих в .then, вы можете связать .catch, который принимает функцию в качестве аргумента. Предоставленная вами функция получит ошибку в качестве аргумента для обработки.

const examplePromise = new Promise(resolve => {
  const data = {
    username: ['a','b', 'c']
  }

  setTimeout(() => {
    resolve({data});
  }, 1000);
})


examplePromise.then(({data}) => {
  console.log(data.username.contains('a'))
}).catch(err => {
  // VM1025 pen.js:13 Uncaught (in promise) TypeError: data.username.contains is not a function
  console.log(err)
})

examplePromise.then(({data}) => {
  console.log('works', data.username.includes('a'))
}).catch(err => {
  console.log(err)
})
...