Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Better support for createPerFieldToJson #1392

Open
akvgergo opened this issue Jan 21, 2024 · 0 comments
Open

Suggestion: Better support for createPerFieldToJson #1392

akvgergo opened this issue Jan 21, 2024 · 0 comments

Comments

@akvgergo
Copy link

akvgergo commented Jan 21, 2024

As far as I can tell, createPerFieldToJson is currently mostly used by other code generators, and is rather impractical to use in other cases. As the name suggests, I would like to be able to only serialize some parts of a model, but the abstract class generated does not expose any methods that would make it easy to do this. If I were to use them in the way that the name suggests, my options are:

  1. Copy-paste the generated code with the key strings, and manually create the methods I need to only serialize some fields of a model.

  2. Mark most fields as nullable and not required, and simply copyWith(), with the unnecessary values nulled.

  3. Create models that interface with the main ones, that have special json handling.

  4. Create another library that does the heavy lifting, generating methods for me that only serialize the given values.

The first option is not great for obvious reasons. The second and third options are better, but it would lead to a lot of unnecessary null handling and boilerplate. The fourth option is ideal, but I honestly lack the expertise to achieve it.

For clarity, here's an example of what I'm trying to achieve. This is a model that we're using:

/// Stores data related to a single storage entry, and the associated product.
@Freezed()
class Stock with _$Stock {
  const Stock._();

  @JsonSerializable(createPerFieldToJson: true)
  const factory Stock({
    required final int id,
    required final int storeId,
    required final int productId,
    required final int amount,
    required final int netPrice,
    @JsonKey(toJson: Util.boolToInt)
    required final bool onDiscount,.
    required final int? discountPercent,
    required final int? discountPrice,
    required final int minimumLevel,
    required final String created,
    required final String modified,
    required final int notificationLevel,
    required final int optimalLevel,
    required final int fullLevel,
    required final String? changelog,
    required final int? purchasePrice,
    @JsonKey(toJson: Util.boolToInt)
    required final bool selectedForPrinting,
    @JsonKey(toJson: Util.boolToInt)
    required final bool active,

    required final String slug,
    required final String? productBarcode,
    required final String? productName,
    required final Product? product,
    required final bool selectedForPurchase,
  }) = _Stock;

  factory Stock.fromJson(dynamic json) => _$StockFromJson(json);

  factory Stock.fromJsonString(String jsonString) => _$StockFromJson(json.decode(jsonString));

  String toJsonString() => json.encode(toJson());

  Future<Product?> loadProduct() async {
    return (await Products.read(productId)).result;
  }
}

I would like to be able to make a method like this:

  static dynamic createPartialJson({
    int? amount,
    int? netPrice,
    bool? onDiscount,
    int? discountPercent,
    int? discountPrice,
  }) {
    ...
  }

So I can do this:

    createPartialJson(
      amount: 20,
      netPrice: 199
    );
    // result: { "amount": 20, net_price: 199}

Use case:

With how our API operates, always sending the entire model is undesirable. Trying to update the changelog, lastModified, or created fields for example will lead to errors. Also, during normal operation, there will be quite a few cases where multiple people will send requests that update the same models. Only sending the minimum of what was changed will help a lot avoiding possible data loss from multiple clients overwriting changes.

Is it possible/within reason to implement this functionality?

small note: Feel free to point me to a dependent library that achieves this, if there are any. 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant