web-dev-qa-db-fra.com

React Native: rejet possible d'une promesse non gérée

Je reçois l'erreur suivante: Possible unhandled promise rejection (id:0: Network request failed

Voici le code de promesse, je ne vois pas ce qui ne va pas ici, des idées?

  return fetch(url)
    .then(function(response){
      return response.json();
    })
    .then(function(json){
      return {
        city: json.name,
        temperature: kelvinToF(json.main.temp),
        description: _.capitalize(json.weather[0].description)
      }
    })
    .catch(function(error) {
    console.log('There has been a problem with your fetch operation: ' + error.message);
    });
}

** Edit: J'ai ajouté une fonction catch et j'ai eu une meilleure erreur You passed an undefined or null state object; instead, use forceUpdate(). index.ios.js:64 undefined

Voici le code index.ios.js. L'URL est correct et me donne les données JSON correctes. Je peux voir avec le journal de la console que region.latitude et region.longitude sont tous deux disponibles dans Api(region.latitude, region.longitude). Mais data n'est pas défini. Je ne suis toujours pas sûr de ce qui se passe, pourquoi il y a un problème avec data et pourquoi il n'est pas défini.

// var React = require('react-native'); --deprecated

// updated
import React from 'react';

// updated
import {
  AppRegistry,
  MapView,
  View,
  Text,
  StyleSheet,
} from 'react-native';

/*
var {
  AppRegistry,
  MapView,
  View,
  Text,
  StyleSheet
} = React;
*/ // -- depreciated 


var Api = require('./src/api');

var Weather = React.createClass({
  getInitialState: function() {
    return {
      pin: {
        latitude: 0,
        longitude: 0
      },
      city: '',
      temperature: '',
      description: ''
    };
  },
  render: function() {
    return <View style={styles.container}>
      <MapView
        annotations={[this.state.pin]}
        onRegionChangeComplete={this.onRegionChangeComplete}
        style={styles.map}>
      </MapView>
      <View style={styles.textWrapper}>
        <Text style={styles.text}>{this.state.city}</Text>
        <Text style={styles.text}>{this.state.temperature}</Text>
        <Text style={styles.text}>{this.state.description}</Text>
      </View>
    </View>
  },
  onRegionChangeComplete: function(region) {
    this.setState({
      pin: {
        longitude: region.longitude,
        latitude: region.latitude
      }
    });

    Api(region.latitude, region.longitude)
      .then((data) => {
        console.log(data);
        this.setState(data);
      });
  }
});




var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'stretch',
    backgroundColor: '#F5FCFF'
  },
  map: {
    flex: 2,
    marginTop: 30
  },
  textWrapper: {
    flex: 1,
    alignItems: 'center'
  },
  text: {
    fontSize: 30
  }
});

AppRegistry.registerComponent('weather', () => Weather);
47
Agent Zebra

la fonction catch de votre api doit renvoyer des données pouvant être gérées par un appel Api dans la classe React ou générer une nouvelle erreur qui devrait être interceptée en utilisant la fonction catch dans votre code de classe React. La dernière approche devrait être comme:

return fetch(url)
.then(function(response){
  return response.json();
})
.then(function(json){
  return {
    city: json.name,
    temperature: kelvinToF(json.main.temp),
    description: _.capitalize(json.weather[0].description)
  }
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
 // ADD THIS THROW error
  throw error;
});

Puis dans votre React Class:

Api(region.latitude, region.longitude)
  .then((data) => {
    console.log(data);
    this.setState(data);
  }).catch((error)=>{
     console.log("Api call error");
     alert(error.message);
  });
42
while1

Vous devez ajouter le catch () à la fin de l'appel Api. Lorsque votre code frappe la variable catch (), il ne renvoie rien. Par conséquent, les données ne sont pas définies lorsque vous essayez d'utiliser setState (). Le message d'erreur vous le dit aussi :)

3
hasseio

Selon cet article , vous devez l'activer dans XCode.

  1. Cliquez sur votre projet dans le navigateur de projet.
  2. Ouvrez l'onglet Info
  3. Cliquez sur la flèche vers le bas à gauche de "Paramètres de sécurité App Transport".
  4. Faites un clic droit sur "Paramètres de sécurité de transport d'application" et sélectionnez Ajouter une ligne.
  5. Pour la rangée créée, définissez la clé "Autoriser les charges arbitraires", tapez boolean et value to YES.

enter image description here

3
Emmanuel Derozin

Ajouter ici mon expérience qui, espérons-le, pourrait aider quelqu'un.

Je rencontrais le même problème sur Android émulateur sous Linux avec un rechargement à chaud. Le code était correct selon la réponse acceptée et l'émulateur pouvait accéder à Internet (j'avais besoin d'un nom de domaine).

Rafraîchissant manuellement l'application l'a fait fonctionner. Alors peut-être que cela a quelque chose à voir avec le rechargement à chaud.

2
stilllife

supprime le dossier de construction projectfile\Android\app\build et lance le projet

0
Mahdi Pourrostam