J'essaie d'utiliser les données de l'API, mais les données dont j'ai besoin sont trouvées pour différentes requêtes. Dans flutter, il y a future.waite et avec cela, je peux faire une demande pour les parties nécessaires de l'API. L'idée est que j'essaie de créer un horaire pour le train. Dans cet horaire de train, j'ai besoin du numéro de train, du nom du quai et de l'heure d'arrivée. J'essaie de tout faire comme décrit dans la documentation et sur la vidéo, mais je ne peux pas le faire, car j'obtiens une erreur 'The method '[]' was called on null. Receiver: null Tried calling: []("st_title")'

Avant de demander ici, j'ai essayé de faire quelque chose comme ceci:

body:ListView.builder(itemBuilder: (context, index){
          return ListTile(
            title: Text(stops[index]['st_title']),

Mais cela ne fonctionne pas et me donne une erreur:

La méthode '[]' a été appelée sur null. Destinataire: null Appel essayé:

J'ai vu une solution à une erreur similaire ici, mais j'ai essayé toutes les solutions et je ne peux pas comprendre exactement ce que je fais mal. Pourriez-vous m'indiquer s'il vous plaît ? Peut-être que je ne réalise pas réellement les concepts de ce que je devrais faire exactement. Pouvez-vous, les gars, m'aider ?

Mon code complet est:

Map <String, dynamic> stops;
  Map <String, dynamic> marhe;
 Map <String, dynamic> arrival;
 
@override
  void initState() {
    // TODO: implement initState
    super.initState();

    fetchData();
  }

 Future fetchData() async{
    String username = '***';
    String password = '***';
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);
  final result = await Future.wait([
    http.get( 'http://link/getTableCur.php?fmt=json',
        headers: <String, String>{'authorization': basicAuth}),
    http.get( 'http://link//getStops.php?fmt=json',
        headers: <String, String>{'authorization': basicAuth}),
    http.get( 'http://link//getMarshes.php?fmt=json',
        headers: <String, String>{'authorization': basicAuth}),
  ]);
  setState(() {
    stops = json.decode(result[0].body);
    marhe = json.decode(result[1].body);
    arrival = json.decode(result[2].body);
  });
  }


  @override


  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
        ),
        body:ListView.builder(itemBuilder: (context, index){
          return ListTile(
            title: Text(stops[index]['st_title']),
            leading: Text(marhe['mr_num']),
            subtitle: Text(arrival['ta_arrivetime'].toString()),
          );
        }
            //title: Text(arrival[index]['tc_arrivetime']?? ''),
          ),

MISE À JOUR!

Merci de m'avoir aidé @Patrick Freitas, j'essayais de faire tout ce qu'il a dit mais maintenant j'obtiens une erreur :

The getter 'length' was called on null.
Receiver: null
Tried calling: length

Pour le code suivant:

 body:  stops.length > 0 ? ListView.builder(
              //itemCount: stops.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                 trailing: Text(marhe[index]["mr_num"]),
                  title: Text(stops[index]['st_title']),
                 // subtitle: Text(arrival[index]["ta_arrivetime"]),
                );
              },
            ) : CircularProgressIndicator()
        )

Aussi quand j'utilise isDataObtained ? ListView.builder{...}:CircularProgressIndicator()

Puis cela me donne un chargement sans fin et aucune donnée n'apparaît à l'écran. Cela donne également une erreur "Error: List<dynamic> is not a subtype of type Map<String, dynamic>" aussi j'ai trouvé la résolution de problème similaire sur cette question - Erreur : List n'est pas un sous-type du type Map

Et mon code ressemble à ceci:

 setState(() {

      stops = json.decode(result[0].body[0]);
      marhe = json.decode(result[1].body[0]);
      arrival = json.decode(result[2].body[0]);
      isDataObtained = true;
    });
  }

Aussi mon json pour tous ces liens ressemble à ceci:

for **getTableAll**
[
  {
    "ta_id": 1,
    "srv_id": 1,
    "st_id": 3026,
    "mr_id": 305,
    "rl_racetype": "B",
    "uniqueid": 21,
    "ta_systime": "2021-03-11 15:01:47",
    "ta_arrivetime": "2021-03-11 15:06:11",
    "mv_id": 957,
    "rc_kkp": "",
    "ta_len2target": 4.996839,
    "u_inv": false
  },
  {
for **getStops**
{
    "st_id": 1,
    "ok_id": "18410",
    "sr_id": 0,
    "st_title": "Station1",
    "st_desc": "Station1",
  },

for **Marshes:** 
[
  {
    "mr_id": 1,
    "tt_id": 1,
    "mt_id": 2,
    "mr_num": "112",
  
  },

Ce sont trois tableaux et j'ai besoin des données des trois tableaux en même temps : comme je l'ai décrit ci-dessus, j'ai besoin de données sur l'heure d'arrivée, le numéro de train et le nom de la plate-forme. J'ai essayé d'utiliser la récupération de données classique comme décrit dans la documentation de flutter, mais rien n'a fonctionné pour moi. Ici sur Stackoverflow, on m'a dit que je devais utiliser Future.wait, mais maintenant je suis bloqué et je me suis perdu.

0
WildHaskyWhiskey 10 mars 2021 à 17:27

1 réponse

Meilleure réponse

Flutter ne sait pas si votre demande asynchrone a déjà été renvoyée, il essaie donc de restituer un tableau sans aucune information. Pour éviter cela, vous pouvez ajouter une validation IF pour vérifier si votre tableau est déjà rempli.

Utiliser un ternaire si :

body:
   stops.length > 0 ? ​
      ListView.builder(...) :
      CircularProgressIndicator() 

Comme vous avez trois tableaux à remplir, vous pouvez créer un booléen pour contrôler si votre requête a déjà rempli les trois, comme isDataObtained.

Map <String, dynamic> stops;
Map <String, dynamic> marhe;
Map <String, dynamic> arrival;
bool isDataObtained = false;


Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(),
            body:
                isDataObtained ? ​
                    ListView.builder(...) :
                    CircularProgressIndicator() 
        )
    )
}


Future fetchData() async{
    final result = await Future.wait([...]);
    setState(() {
        stops = json.decode(result[0].body);
        marhe = json.decode(result[1].body);
        arrival = json.decode(result[2].body);
        isDataObtained = true;
    });
}
0
Patrick Freitas 10 mars 2021 à 14:42