Search code examples
flutterlistdartobjectmodel

Error Unhandled Exception: Converting object to an encodable object failed: Instance of 'listActivities' when i am trying to add new data to list


so i am trying to add a new object to activity and i store it in local storage, the code looks like this

 pushObjectWisata(selectedIndex, selectedObjectId) async {

    PengunjungModel dataObjectWisata = listObjectWisata
        .firstWhere((element) => element.id == selectedObjectId);


    listAktifitas[selectedIndex].dataAktifitas!.add(dataObjectWisata);

    await saveListAktifitas(listAktifitas);
  }

but i got this error:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Converting object to an encodable object failed: Instance of 'listActivities'.

listAktifitas it self is a list with multilevel object. the model look like this

class listActivities {
  String? namaAktifitas;
  int? statusAktifitas;
  int? countActivity;
  String? thumbnail;
  List<PengunjungModel>? dataAktifitas;

  listActivities({
    this.namaAktifitas,
    this.statusAktifitas,
    this.countActivity,
    this.thumbnail,
    this.dataAktifitas,
  });

  factory listActivities.fromJson(Map<String, dynamic> json) => listActivities(
        namaAktifitas: json['namaAktifitas'].toString(),
        countActivity: json['countActivity'],
        statusAktifitas: json['statusAktifitas'],
        thumbnail: json['thumbnail'].toString(),
        dataAktifitas: List<PengunjungModel>.generate(
          json['dataAktifitas'].length,
          (index) => PengunjungModel.fromJson(
              json['dataAktifitas'][index] ?? <String, dynamic>{}),
        ),
      );

  static List<listActivities> fromJsonList(dynamic jsonList) {
    final listAktifitas = <listActivities>[];
    if (jsonList == null) return listAktifitas;

    if (jsonList is List<dynamic>) {
      for (final json in jsonList) {
        listAktifitas.add(
          listActivities.fromJson(json),
        );
      }
    }

    return listAktifitas;
  }

  factory listActivities.fromRawJson(String str) =>
      listActivities.fromJson(jsonDecode(str));

  String toRawJson() => jsonEncode(toJson());

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['namaAktifitas'] = namaAktifitas;
    data['statusAktifitas'] = statusAktifitas;
    data['countActivity'] = countActivity;
    data['thumbnail'] = thumbnail;
    data['dataAktifitas'] = dataAktifitas;
    return data;
  }
}

as you can see, it has relation to another list which is pengungungModel List. and the model look like this:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:sbh_v2/model/pariwisata/foto.dart';
import 'package:sbh_v2/model/pariwisata/kategori_pengunjung.dart';

class PengunjungModel {
  String? title;
  int? id;
  String? harga_terendah;
  String? harga_tertinggi;
  String? deskripsi;
  String? jam_buka;
  String? jam_tutup;
  String? alamat;
  String? fasilitas;
  double? lat;
  double? lng;
  List<Foto>? list_foto = <Foto>[];
  KategoriPengunjung? kategoriPengunjung;

  PengunjungModel(
      {this.id,
      this.title,
      this.harga_terendah,
      this.harga_tertinggi,
      this.deskripsi,
      this.alamat,
      this.list_foto,
      this.jam_tutup,
      this.jam_buka,
      this.fasilitas,
      this.lat,
      this.lng,
      this.kategoriPengunjung});

  factory PengunjungModel.fromJson(Map<String, dynamic> json) =>
      PengunjungModel(
        id: json['id'],
        title: json['title'] ?? "-",
        alamat: json['alamat'] ?? "-",
        jam_buka: json['jam_buka'] ?? "-",
        jam_tutup: json['jam_tutup'] ?? "-",
        fasilitas: json['fasilitas'],
        lat: double.parse(json['lat'] ?? '0'),
        lng: double.parse(json['lng'] ?? '0'),
        harga_terendah: json['harga_terendah'] ?? "",
        harga_tertinggi: json['harga_tertinggi'] ?? "",
        deskripsi: json['deskripsi'] ?? "-",
        list_foto: List<Foto>.generate(
          json['foto'].length,
          (index) => Foto.formJson(
            json['foto'][index] ?? <String, dynamic>{},
          ),
        ),
        kategoriPengunjung: KategoriPengunjung.fromJson(
            json['kategori_layanan_pengunjung'] ?? <String, dynamic>{}),
      );

  factory PengunjungModel.fromRawJson(String str) =>
      PengunjungModel.fromJson(jsonDecode(str));
}

basically i tried to add an object of pengunjungModel data with spesic id to a listAktifitas with specific index...

in pushObjectWisata i tried to print the selectedIndex and selectedObjectId and it works fine. but when i tried to print the dataObjectWisata it return that error and the same thing happen when i add the dataObjectWisata to listAktivitas.

i dont know what i dont understand. but maybe this is because of the model of those two..

please help me.... thank you


Solution

  • You're encountering an error while trying to encode an object for storage, possibly while using JSON encoding. The error message " Converting object to an encodable object failed" typically occurs when you're trying to serialize an object that doesn't have a corresponding JSON representation.In your code snippet, you're trying to save listAktifitas, which contains objects of type listActivities, to storage. To resolve this error, you need to ensure that all objects within listAktifitas are encodable.

    To fix the error, you need to ensure that PengunjungModel also has a toJson() method to convert it into a JSON-encodable format. Here's how you can modify the toJson() method in listActivities to properly encode dataAktifitas.

    Update your listActivities class toJson() method like this:

    Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
      data['namaAktifitas'] = namaAktifitas;
      data['statusAktifitas'] = statusAktifitas;
      data['countActivity'] = countActivity;
      data['thumbnail'] = thumbnail;
      data['dataAktifitas'] = dataAktifitas != null
          ? dataAktifitas!.map((pengunjung) => pengunjung.toJson()).toList()
          : null; // Check if dataAktifitas is null to avoid runtime error
      return data;
    }
    

    Ensure that PengunjungModel also has a proper toJson() method implemented.

    Map<String, dynamic> toJson() {
     final Map<String, dynamic> data = new Map<String, dynamic>();
        data['id'] = this.id;
        data['title'] = this.title;
        data['harga_terendah'] = this.harga_terendah;
        data['harga_tertinggi'] = this.harga_tertinggi;
        data['deskripsi'] = this.deskripsi;
        data['jam_buka'] = this.jam_buka;
        data['jam_tutup'] = this.jam_tutup;
        data['alamat'] = this.alamat;
        data['fasilitas'] = this.fasilitas;
        data['lat'] = this.lat.toString();
        data['lng'] = this.lng.toString();
        if (this.list_foto != null) {
          data['foto'] = this.list_foto!.map((v) => v.toJson()).toList();
        }
        if (this.kategoriPengunjung != null) {
          data['kategori_layanan_pengunjung'] = this.kategoriPengunjung!.toJson();
        }
        return data;
      }
    

    Modify the pushObjectWisata function like this:

    Future<void> pushObjectWisata(int selectedIndex, String selectedObjectId) async{
    
      PengunjungModel? dataObjectWisata = listObjectWisata.firstWhereOrNull(
        (element) => element.id == selectedObjectId,
      );
    
      if (dataObjectWisata != null) {
        // Check if the dataAktifitas list is initialized
        if (listAktifitas[selectedIndex].dataAktifitas == null) {
          listAktifitas[selectedIndex].dataAktifitas = [];
        }
    
        // Add the dataObjectWisata to the dataAktifitas list
        listAktifitas[selectedIndex].dataAktifitas!.add(dataObjectWisata);
    
        // Convert listAktifitas to a JSON string
        String jsonListAktifitas = jsonEncode(
          listAktifitas.map((aktivitas) => aktivitas.toJson()).toList(),
        );
    
        // Save the JSON string to storage
        await saveListAktifitas(jsonListAktifitas);
      } else {
        print('PengunjungModel with id $selectedObjectId not found.');
      }
    }
    

    Check the definition of your all class. Make sure all its properties are primitive types (like String, int, double, bool), lists, or maps, or that they implement a toJson() method if they're custom classes.ensure that you have a class called Foto, add the toJson() method to it.