Преобразование вложенного объекта в Flutter из Json возвращает null

#json #flutter #object #dart #constructor

#json #flutter #объект #dart #конструктор

Вопрос:

У меня есть такой вложенный объект, только немного больше:

 "name": "String",       
    "exercise": [               
                   {                
                   "index": 1,                                  
                   }            
            ],              
    "pause": [              
        {"index":2},                        
    ]           
  

Я преобразую упражнение и паузу в строку Json и сохраняю их в столбце в SQFLite.

Проблема

Когда я читаю данные, все работает нормально, включая список (не вложенный), но оба списка вложенного объекта пусты, когда я считываю значение вложенного объекта, это выдает ошибку.

 item.exercise[0].index.toString()

Valid Value range is empty: 0
  

Когда я только читаю item.exercise.toString() , он возвращается [] . Без != null ? [...] : List<Exercise>() этого также выдает ошибку

Данные, которые я получаю из своей базы данных (сокращенные)

Список:

 [{name: number 1, id: 56, exercise: [{"index":1,"weightGoal":[15,16,17]}, {"index":3,"weightGoal":[15,16,17]}], pause: [{"index":2}]},{"index":4}]}]
  

Что я с этим делаю

Здесь я пытаюсь просмотреть список и преобразовать его в список PlanModel:

 List<PlanModel> list =
        res.isNotEmpty ? res.map((c) => PlanModel.fromJson(c)).toList() : [];
    return list;
  

Полная модель

 PlanModel planModelFromJson(String str) => PlanModel.fromJson(json.decode(str));

String planModelToJson(PlanModel data) => json.encode(data.toJson());

class PlanModel {
  PlanModel({
    this.name,
    this.id,
    this.workoutDays,
    this.pastId,
    this.timesDone,
    this.exercise,
    this.pause,
  });

  String name;
  int id;
  List<String> workoutDays;
  int pastId;
  int timesDone;
  List<Exercise> exercise;
  List<Pause> pause;

  factory PlanModel.fromJson(Map<String, dynamic> json) => PlanModel(
    name: json["name"],
    id: json["id"],
    workoutDays: List<String>.from(jsonDecode(json["workoutDays"])),
    pastId: json["pastId"],
    timesDone: json["timesDone"],
    exercise: json["Exercise"] != null ? new List<Exercise>.from(json["Exercise"].map((x) => Exercise.fromJson(x))): List<Exercise>(),
    pause: json["Pause"] != null ? new List<Pause>.from(json["Pause"].map((x) => Pause.fromJson(x))): List<Pause>(),
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "id": id,
    "workoutDays": List<dynamic>.from(workoutDays.map((x) => x)),
    "pastId": pastId,
    "timesDone": timesDone,
    "Exercise": List<dynamic>.from(exercise.map((x) => x.toJson())),
    "Pause": List<dynamic>.from(pause.map((x) => x.toJson())),
  };



}

class Exercise {
  Exercise({
    this.index,
    this.name,
    this.goal,
    this.repGoal,
    this.weightGoal,
    this.timeGoal,
    this.setGoal,
  });

  int index;
  String name;
  int goal;
  int repGoal;
  List<int> weightGoal;
  int timeGoal;
  List<String> setGoal;

  Exercise.fromJson(dynamic json) {
    // anything that is wrapped around with this [] in json is converted as list
    // anything that is wrapped around with this {} is map
    index = json["index"];
    name = json["name"];
    goal = json["goal"];
    repGoal = json["repGoal"];
    weightGoal = json["weightGoal"] != null ? json["weightGoal"].cast<int>() : [];
    timeGoal = json["timeGoal"];
    setGoal = json["setGoal"] != null ? json["setGoal"].cast<String>() : [];
  }

  Map<String, dynamic> toJson() => {
    "index": index,
    "name": name,
    "goal": goal,
    "repGoal": repGoal,
    "weightGoal": List<dynamic>.from(weightGoal.map((x) => x)),
    "timeGoal": timeGoal,
    "setGoal": List<dynamic>.from(setGoal.map((x) => x)),
  };
}

class Pause {
  Pause({
    this.index,
    this.timeInMilSec,
  });

  int index;
  int timeInMilSec;

  factory Pause.fromJson(Map<String, dynamic> json) => Pause(
    index: json["index"],
    timeInMilSec: json["timeInMilSec"],
  );

  Map<String, dynamic> toJson() => {
    "index": index,
    "timeInMilSec": timeInMilSec,
  };
}
  

Комментарии:

1. Я не уверен, но я думаю, что ключи чувствительны к регистру. Вы используете: json [«Упражнение»] и json [«Пауза»]

2. @ClaudioCastro спасибо за ваш комментарий, но это нормально, я также инициализировал оба из них в верхнем регистре, поскольку переменных нет, скорее классы.

3. @M123 не могли бы вы, пожалуйста, предоставить нам все данные, которые вы получаете, полную версию PlanModel и полную версию вашего упражнения, чтобы я мог протестировать его и заставить что-то работать из него?

4. @manofknowledge вот так

5. упражнение в нижнем регистре в базе данных, но вы пытаетесь получить его, используя упражнение с прописной буквой E

Ответ №1:

Сначала прочитайте это.

Вам нужно немного изменить этот код, чтобы он работал на вас, но идея в том, что; также прочитайте комментарий в коде.

если строка json поставляется с [] другими, json.decode будет декодировать ее как List<Map> .

если он поставляется с {} этим json.decode будет декодировать его как Map .

примечание: будьте осторожны при использовании дженериков в json.decode я не рекомендую.

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

также основной конструктор Exercise , который вы можете использовать для исходных данных.

 import 'dart:convert';
class Exercise{
  Exercise({this.index, 
            this.name, 
            this.repGoal, 
            this.weightGoal, 
            this.setGoal});
  
  String index;
  String name;
  String repGoal;
  String weightGoal;
  String setGoal;


Exercise.fromJson(dynamic json) : 
    // anything that is wrapped around with this [] in json is converted as list
    // anything that is wrapped around with this {} is map
    index = json["exercise"][0]["index"].toString(),
    name = json["name"].toString(),
    repGoal = json["repGoal"].toString(),
    weightGoal = json["weightGoal"].toString(),
    setGoal = json["setGoal"].toString();
  
  
}

void main(){
  String jsonString = '{name: number 1, id: 56, exercise: [{"index":1,"weightGoal":[15,16,17], pause: [{"index":2}]}';
  Map json = json.decode(jsonString);
  Exercise.fromJson(json);
  
}
  

Комментарии:

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

Ответ №2:

Я это выяснил 🙂

Я перестроил свой FromJSON на это, особенно важен jsonDecode, потому json["exercise "] что это была всего лишь строка.

 PlanModel.fromJson(dynamic json) {
    name = json["name"];
    if (json["exercise"] != null) {
      exercise = [];
      jsonDecode(json["exercise"]).forEach((v) {
        exercise.add(Exercise.fromJson(v));
      });
    }}
  

теперь я могу получить к нему доступ с помощью

 PlanModel item = snapshot.data[index];

item.exercise[0].timeGoal.toString()
    
  

Комментарии:

1. Я действительно рад за вас! извините, я не смог ответить раньше.

2. @manofknowledge Спасибо, и никаких проблем, я просто дал вам награду bc, поскольку вы разобрались с проблемой, спасибо за это