简体   繁体   中英

I am having a hard time getting data from an nested object in a json map using dart/flutter

As the title states, I am trying to pull data from a nested object with a json MAP. I hope I am describing this correctly. I am new to dart and still growing as a programmer. Here is the code for my model.

class Device {
 List<DevicesModel> _devices = [];
 Page? _page;
 List<DevicesModel> get devices => _devices;

Device({required devices, required page}) {
 this._devices = devices;
 this._page = page;
}

Device.fromJson(Map<String, dynamic> json) {
   if (json['devices'] != null) {
     _devices = <DevicesModel>[];
     json['devices'].forEach((v) {
       _devices.add(DevicesModel.fromJson(v));
     });
    }
  }
}

class DevicesModel {
  late final String deviceId;
  String? publicId;
  String? companyId;
  late final String company;
  late final String label;
  String? imei;
  String? sim;
  String? mobileProviderId;
  String? mobileProvider;
  String? hologramDeviceId;
  String? hologramLinkId;
  String? firmwareVersionId;
  String? version;
  String? formattedVersion;
  String? deviceTypeId;
  String? deviceType;
  String? ipAddress;
  String? recordInterval;
  String? uploadInterval;
  String? powerMode;
  String? connectivity;
  String? connectivityClass;
  String? usersLastRecordDate;
  String? gmtLastRecordDate;
  String? battery;
  String? batteryPercentage;
  String? batteryClass;
  String? batteryIcon;
  String? signalQuality;
  late final String signalQualityClass;
  String? signalQualityText;
  String? signalQualityIcon;
  String? queuedRecords;
  String? command;
  String? status;
  String? statusClass;
  String? purchaseDate;
  String? warrantyPeriod;
  String? warrantyExpires;
  String? warrantyStatus;
  String? temperatureClass;
  late final String temperatureMetric;
  late final String temperatureImperial;
  String? surgeProtection;
  String? totalProducts;
  Null temperatureLowThreshold;
  Null temperatureHighThreshold;
  Null notes;
  Null importId;
  String? deleted;
  String? createdBy;
  String? lastUpdatedBy;
  Null deletedBy;
  Null dateCreated;
  String? dateModified;
  Null dateDeleted;
  String? scope;
  String? owner;
  late List<Ports> ports;

DevicesModel(
  {required this.deviceId,
  this.publicId,
  this.companyId,
  required this.company,
  required this.label,
  this.imei,
  this.sim,
  this.mobileProviderId,
  this.mobileProvider,
  this.hologramDeviceId,
  this.hologramLinkId,
  this.firmwareVersionId,
  this.version,
  this.formattedVersion,
  this.deviceTypeId,
  this.deviceType,
  this.ipAddress,
  this.recordInterval,
  this.uploadInterval,
  this.powerMode,
  this.connectivity,
  this.connectivityClass,
  this.usersLastRecordDate,
  this.gmtLastRecordDate,
  this.battery,
  this.batteryPercentage,
  this.batteryClass,
  this.batteryIcon,
  this.signalQuality,
  required this.signalQualityClass,
  this.signalQualityText,
  this.signalQualityIcon,
  this.queuedRecords,
  this.command,
  this.status,
  this.statusClass,
  this.purchaseDate,
  this.warrantyPeriod,
  this.warrantyExpires,
  this.warrantyStatus,
  this.temperatureClass,
  required this.temperatureMetric,
  required this.temperatureImperial,
  this.surgeProtection,
  this.totalProducts,
  this.temperatureLowThreshold,
  this.temperatureHighThreshold,
  this.notes,
  this.importId,
  this.deleted,
  this.createdBy,
  this.lastUpdatedBy,
  this.deletedBy,
  this.dateCreated,
  this.dateModified,
  this.dateDeleted,
  this.scope,
  this.owner,
  required this.ports
});

DevicesModel.fromJson(Map<String, dynamic> json) {
  deviceId = json['device_id'];
  publicId = json['public_id'];
  companyId = json['company_id'];
  company = json['company'] ?? 'unknown';
  label = json['label'] ?? 'unknown';
  imei = json['imei'];
  sim = json['sim'];
  mobileProviderId = json['mobile_provider_id'];
  mobileProvider = json['mobile_provider'];
  hologramDeviceId = json['hologram_device_id'];
  hologramLinkId = json['hologram_link_id'];
  firmwareVersionId = json['firmware_version_id'];
  version = json['version'];
  formattedVersion = json['formatted_version'];
  deviceTypeId = json['device_type_id'];
  deviceType = json['device_type'];
  ipAddress = json['ip_address'];
  recordInterval = json['record_interval'];
  uploadInterval = json['upload_interval'];
  powerMode = json['power_mode'];
  connectivity = json['connectivity'];
  connectivityClass = json['connectivity_class'];
  usersLastRecordDate = json['users_last_record_date'];
  gmtLastRecordDate = json['gmt_last_record_date'];
  battery = json['battery'];
  batteryPercentage = json['battery_percentage'];
  batteryClass = json['battery_class'];
  batteryIcon = json['battery_icon'];
  signalQuality = json['signal_quality'];
  signalQualityClass = json['signal_quality_class'];
  signalQualityText = json['signal_quality_text'];
  signalQualityIcon = json['signal_quality_icon'];
  queuedRecords = json['queued_records'];
  command = json['command'];
  status = json['status'];
  statusClass = json['status_class'];
  purchaseDate = json['purchase_date'];
  warrantyPeriod = json['warranty_period'];
  warrantyExpires = json['warranty_expires'];
  warrantyStatus = json['warranty_status'];
  temperatureClass = json['temperature_class'];
  temperatureMetric = json['temperature_metric'] ?? 'n/a';
  temperatureImperial = json['temperature_imperial'] ?? 'n/a';
  surgeProtection = json['surge_protection'];
  totalProducts = json['total_products'];
  temperatureLowThreshold = json['temperature_low_threshold'];
  temperatureHighThreshold = json['temperature_high_threshold'];
  notes = json['notes'];
  importId = json['import_id'];
  deleted = json['deleted'];
  createdBy = json['created_by'];
  lastUpdatedBy = json['last_updated_by'];
  deletedBy = json['deleted_by'];
  dateCreated = json['date_created'];
  dateModified = json['date_modified'];
  dateDeleted = json['date_deleted'];
  scope = json['scope'];
  owner = json['owner'];
  if (json['ports'] != null) {
    ports = <Ports>[];
    json['ports'].forEach((v) {
      ports.add(new Ports.fromJson(v));
    });
   }
  }
 }

 class Ports {
  List<PortsModel> _ports = [];
  List<PortsModel> get ports => _ports;

 Ports({required ports}) {
  this._ports = ports;
 }

 Ports.fromJson(Map<String, dynamic> json) {
  if (json['ports'] != null) {
   _ports = <PortsModel>[];
   json['ports'].forEach((v) {
    _ports.add(PortsModel.fromJson(v));
   });
  }
 }
}

class PortsModel {
 String? devicePortsId;
 String? deviceId;
 String? companyId;
 String? company;
 String? productId;
 late final String productName;
 String? portNumber;
 String? version;
 String? sensorTypeId;
 String? sensorType;
 String? sensorDescription;
 String? imperialSymbol;
 String? metricSymbol;
 String? fillVolumeGallons;
 String? fillVolumeLiters;
 String? totalGallonsCapacity;
 String? totalLitersCapacity;
 String? percentFull;
 String? tankTypeId;
 String? tankType;
 String? slug;
 String? imageUrl;
 String? formula;
 String? reorderYellow;
 String? reorderRed;
 String? deleted;
 Null? createdBy;
 String? lastUpdatedBy;
 Null? deletedBy;
 String? dateCreated;
 String? dateModified;
 Null? dateDeleted;
 String? scope;
 String? owner;

PortsModel(
  {this.devicePortsId,
  this.deviceId,
  this.companyId,
  this.company,
  this.productId,
  required this.productName,
  this.portNumber,
  this.version,
  this.sensorTypeId,
  this.sensorType,
  this.sensorDescription,
  this.imperialSymbol,
  this.metricSymbol,
  this.fillVolumeGallons,
  this.fillVolumeLiters,
  this.totalGallonsCapacity,
  this.totalLitersCapacity,
  this.percentFull,
  this.tankTypeId,
  this.tankType,
  this.slug,
  this.imageUrl,
  this.formula,
  this.reorderYellow,
  this.reorderRed,
  this.deleted,
  this.createdBy,
  this.lastUpdatedBy,
  this.deletedBy,
  this.dateCreated,
  this.dateModified,
  this.dateDeleted,
  this.scope,
  this.owner});

PortsModel.fromJson(Map<String, dynamic> json) {
  devicePortsId = json['device_ports_id'];
  deviceId = json['device_id'];
  companyId = json['company_id'];
  company = json['company'];
  productId = json['product_id'];
  productName = json['product_name'] ?? 'unknown';
  portNumber = json['port_number'];
  version = json['version'];
  sensorTypeId = json['sensor_type_id'];
  sensorType = json['sensor_type'];
  sensorDescription = json['sensor_description'];
  imperialSymbol = json['imperial_symbol'];
  metricSymbol = json['metric_symbol'];
  fillVolumeGallons = json['fill_volume_gallons'];
  fillVolumeLiters = json['fill_volume_liters'];
  totalGallonsCapacity = json['total_gallons_capacity'];
  totalLitersCapacity = json['total_liters_capacity'];
  percentFull = json['percent_full'];
  tankTypeId = json['tank_type_id'];
  tankType = json['tank_type'];
  slug = json['slug'];
  imageUrl = json['image_url'];
  formula = json['formula'];
  reorderYellow = json['reorder_yellow'];
  reorderRed = json['reorder_red'];
  deleted = json['deleted'];
  createdBy = json['created_by'];
  lastUpdatedBy = json['last_updated_by'];
  deletedBy = json['deleted_by'];
  dateCreated = json['date_created'];
  dateModified = json['date_modified'];
  dateDeleted = json['date_deleted'];
  scope = json['scope'];
  owner = json['owner'];
 }
}

class Page {
 int? totalRecords;
 int? pageNum;
 int? pageSize;
 Null? previousPage;
 String? nextPage;
 Null? searchString;

Page(
  {this.totalRecords,
  this.pageNum,
  this.pageSize,
  this.previousPage,
  this.nextPage,
  this.searchString});

Page.fromJson(Map<String, dynamic> json) {
  totalRecords = json['total_records'];
  pageNum = json['page_num'];
  pageSize = json['page_size'];
  previousPage = json['previous_page'];
  nextPage = json['next_page'];
  searchString = json['search_string'];
  }
}

Followed by the place I am trying to print out the nested data.

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:gateway_device/controllers/device_controller.dart';
import 'package:gateway_device/flutter_flow/flutter_flow_theme.dart';
import 'package:gateway_device/models/devices_model.dart';
import 'package:gateway_device/routes/route_helper.dart';
import 'package:gateway_device/tank_product/tank_product_widget.dart';
import 'package:get/get.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';

class TankProductComponent extends StatefulWidget {
  TankProductComponent({Key? key}) : super(key: key);

  @override
  State<TankProductComponent> createState() => _TankProductComponent();
}

class _TankProductComponent extends State<TankProductComponent> {
  @override
  Widget build(BuildContext context) {
    return GetBuilder<DeviceController>(builder: (devices) {
      // print(devices);

      return Container(
        height: 514,
        child: ListView.builder(
          physics: AlwaysScrollableScrollPhysics(),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          itemCount: 3,
          itemBuilder: (context, position) {
            return _buildPageItem(position, devices.deviceList[position]);
          }),
       );
     });
    }

    Widget _buildPageItem(int index, DevicesModel device) {

      getPorts() {
        var ports = device.ports;
        if (device.ports != [null]) {
          return ports;
        }
      }

      print(getPorts());
    }
   }

The issue that I am having is that the error tells me that 'LateError (LateInitializationError: Field 'ports' has not been initialized.)'

I am struggling to figure out how to do this successfully. Please help! You have my sincere thanks in advance.

The error is most likely caused by this:

if (json['ports'] != null) {
    ports = <Ports>[];
    json['ports'].forEach((v) {
      ports.add(new Ports.fromJson(v));
    });
   }
  }

You are conditionally initializing the ports field of your model if the json response contains ports. Changing the code to this would likely fix your problem:

    ports = <Ports>[];
    if (json['ports'] != null) {
            json['ports'].forEach((v) {
              ports.add(new Ports.fromJson(v));
            });
          }
    }

Note that your field is late, but it must be initialized before it's used, so conditional initialization is bound to cause trouble. Also I suggest grouping related fields into models, it's not good practice to have a model with 100 fields.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM