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

feat: Add copyWith method to all models #624

Closed
wants to merge 1 commit into from

Conversation

M123-dev
Copy link
Member

What

Adds copyWith methods to all JsonSerializable models we have

My first try was to use freezed as this can add a copyWith method to JsonSerializable but because we have a lot of customization around languages and so on I decided to go for this simpler method.

For most classes it was just adding a @CopyWith() decorator others needed a change in the constructor to use named parameter.

I added it to all classes in a first run, if there are some were we don't need it I'am happy to remove them

For

openfoodfacts/smooth-app#3059
openfoodfacts/smooth-app#3263
...

Copy link
Contributor

@monsieurtanuki monsieurtanuki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @M123-dev!
A lot to review, but each time it's rather quick!

TBH, I cannot picture exactly the added value of that "CopyWith" feature, more specifically in the context of openfoodfacts/smooth-app#3059 and openfoodfacts/smooth-app#3263.

In those Smoothie issues, we need to "merge" two Products (the second on top on the first, only for the second's non null fields), like inputProduct.merge(product: changes), or Product.merge(product1, product2).
And from what I saw in the generated code it's just about individual fields. Like product1.copyWith(lang: 'de').
If so, that would mean that we would need to list all the fields of the second product and then use copyWith just on it, which is more a pain in the neck than a good feature.

And in dart, you can already write easily Product(barcode: '1234')..lang='de'..website='https://...'.

Therefore, I think we need at least a relevant example of the use of copyWith. Would you please share one?

Beyond that, you introduced slight breaking changes, but as it's for classes that are not very interesting I'm sure you'd agree to rollback your changes there, as you suggested in the OP.

@JsonSerializable()
class TaxonomyAdditive extends JsonObject {
TaxonomyAdditive(
TaxonomyAdditive({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.

@JsonSerializable()
class TaxonomyAllergen extends JsonObject {
TaxonomyAllergen(
TaxonomyAllergen({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.

@JsonSerializable()
class TaxonomyCategory extends JsonObject {
TaxonomyCategory(
TaxonomyCategory({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.

@JsonSerializable()
class TaxonomyCountry extends JsonObject {
TaxonomyCountry();
TaxonomyCountry({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did copy_with force you to do that?

@JsonSerializable()
class TaxonomyIngredient extends JsonObject {
TaxonomyIngredient(
TaxonomyIngredient({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.

@JsonSerializable()
class TaxonomyOrigin extends JsonObject {
TaxonomyOrigin();
TaxonomyOrigin({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did copy_with force you to do that?

@JsonSerializable()
class TaxonomyPackaging extends JsonObject {
TaxonomyPackaging();
TaxonomyPackaging({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

@JsonSerializable()
class TaxonomyPackagingMaterial extends JsonObject {
TaxonomyPackagingMaterial();
TaxonomyPackagingMaterial({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

@JsonSerializable()
class TaxonomyPackagingRecycling extends JsonObject {
TaxonomyPackagingRecycling();
TaxonomyPackagingRecycling({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

@JsonSerializable()
class TaxonomyPackagingShape extends JsonObject {
TaxonomyPackagingShape();
TaxonomyPackagingShape({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

@M123-dev
Copy link
Member Author

Ohh, my bad @monsieurtanuki it makes sense that these methods do not make sense (at least for us), I was a bit hasty with the implementation.

@M123-dev M123-dev closed this Nov 22, 2022
@monsieurtanuki
Copy link
Contributor

Thank you anyway for your attempt @M123-dev!

@M123-dev
Copy link
Member Author

So looking at the problem how we actually have it.

  • We need a way to combine two objects
  • Without specifying every property
  • Preferably without having to write all properties
  • My idea for this is to convert both passed objects to JSON and then into to a map and then just calling
    Map.addAll(), this doesn't work for nested properties though. Do you have another idea?

@monsieurtanuki
Copy link
Contributor

@M123-dev Actually I think I had a specific need like that in openfoodfacts/smooth-app#3339 (I created a TODO about it): a clean copy of a Product(like you suggested, a sort of fromJson(toJson)).

Should we generalize that? I don't know. For the moment we only have this specific need for Product.

Another grander idea would be to code a bit like in Nutriments: just keep the json map and create getter/setter for all "json fields".
But it would be a bit out of proportions: refactoring all our classes because for one single need in Smoothie we may find interesting to use a copyWith/merge method on some fields of Product...

If you feel like refactoring in general, I would suggest #450. Would impact all files, with breaking changes. But the code would be cleaner afterwards.

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

Successfully merging this pull request may close these issues.

2 participants