Как декодировать строку в JSON?

Я не знаю, как декодировать строку в JSON, мне необходимо декодировать объект типа Book и добавить новый json объект в коллекцию. Как мне это лучше реализовать? Строка, где я пытаюсь это сделать:

cart.addToCart(CartElement.fromJson(
   jsonDecode('{"id": ${cart.total+1}, "quantity": 
   ${searchBookInList(cart.items, item)+1}, "book": $item}')
));

Класс Book:


    Book bookFromJson(String str) => Book.fromJson(json.decode(str));

    String bookToJson(Book data) => json.encode(data.toJson());

    class Book {
      Book({
        this.id,
        this.idOfGenre,
        this.isbn,
        this.name,
        this.author,
        this.genre,
        this.year,
        this.quantityOfPages,
        this.publisher,
        this.linkImg,
        this.price,
        this.quantityInStock,
      });

      int id;
      int idOfGenre;
      String isbn;
      String name;
      String author;
      String genre;
      int year;
      int quantityOfPages;
      String publisher;
      String linkImg;
      int price;
      int quantityInStock;

      factory Book.fromJson(Map<String, dynamic> json) => Book(
        id: json["id"],
        idOfGenre: json["idOfGenre"],
        isbn: json["ISBN"],
        name: json["name"],
        author: json["author"],
        year: json["year"],
        quantityOfPages: json["quantityOfPages"],
        publisher: json["publisher"],
        linkImg: json["linkImg"],
        price: json["price"],
        quantityInStock: json["quantityInStock"],
      );

      Map<String, dynamic> toJson() => {
        "id": id,
        "id_of_genre": idOfGenre,
        "ISBN": isbn,
        "name": name,
        "author": author,
        "year": year,
        "quantity_of_pages": quantityOfPages,
        "publisher": publisher,
        "link_IMG": linkImg,
        "price": price,
        "quantity_in_stock": quantityInStock,
      };
    }

Класс CartElement:


    CartElement cartElementFromJson(String str) => CartElement.fromJson(json.decode(str));

    String cartElementToJson(CartElement data) => json.encode(data.toJson());

    class CartElement {
      CartElement({
        this.id,
        this.quantity,
        this.book,
      });

      int id;
      int quantity;
      Book book;

      factory CartElement.fromJson(Map<String, dynamic> json) => CartElement(
        id: json["id"],
        quantity: json["quantity"],
        book: json["Book"],
      );

      Map<String, dynamic> toJson() => {
        "id": id,
        "quantity": quantity,
        "Book": book,
      };
    }

Сама ошибка:

    The following FormatException was thrown while handling a gesture:
    Unexpected character (at character 34)
    {"id": 1, "quantity": 1, "book": Instance of 'Book'}
                                     ^

    When the exception was thrown, this was the stack: 
    #0      _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
    #1      _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1271:9)
    #2      _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:936:22)
    #3      _parseJson (dart:convert-patch/convert_patch.dart:40:10)
    #4      JsonDecoder.convert (dart:convert/json.dart:505:36)
    ...
    Handler: "onLongPress"
    Recognizer: LongPressGestureRecognizer#41046
      debugOwner: GestureDetector
      state: possible


Ответы (1 шт):

Автор решения: MiT

Вы передаете в jsonDecode объект, а не Json, toJson() преобразует объект в Json:

cart.addToCart(CartElement.fromJson(
  jsonDecode('{"id": ${cart.total+1}, "quantity": ${searchBookInList(cart.items, item)+1}, "book": bookToJson(item.toJson())}')
));

Второй способ через copyWith, он лучше, тем что нет лишний сериализации:

class CartElement {
  CartElement({
    this.id,
    this.quantity,
    this.book,
  });

  int id;
  int quantity;
  Book book;

  CartElement copyWith({int id, int quantity, Book book}) => CartElement(
        id: id ?? this.id,
        quantity: quantity ?? this.quantity,
        book: book ?? this.book,
      );
...
}

...

CartElement cart = CartElement.fromJson(jsonDecode('{"id": ${cart.total+1}, "quantity": ${searchBookInList(cart.items, item)+1}}'));
cart.addToCart(cart.copyWith(book: item));

factory Book.fromJson(Map<String, dynamic> json) => Book(
    id: json["id"] == null ? null : json["id"],
    idOfGenre: json["id_of_genre"] == null ? null : json["id_of_genre"],
    ...
);

Map<String, dynamic> toJson() => {
    "id": id == null ? null : id,
    "id_of_genre": idOfGenre == null ? null : idOfGenre,
    ...
};
→ Ссылка