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

support for nested items in @JsonKey(name:) #490

Closed
KorbinianMossandl opened this issue May 22, 2019 · 31 comments
Closed

support for nested items in @JsonKey(name:) #490

KorbinianMossandl opened this issue May 22, 2019 · 31 comments

Comments

@KorbinianMossandl
Copy link

KorbinianMossandl commented May 22, 2019

It would be great if we could directly access nested items in the name String of @JsonKey. Consider this Json:

"root_item": {
    "items": [
        {
            "name": "first nested item"
        },
        {
            "name": "second nested item"
        }
    ]
}

I would like to do:

@JsonKey(name: "root_item/items")
List<NestedItem> nestedItems;

Sorry if this is already possible, but i could not find anything.

@kevmoo
Copy link
Collaborator

kevmoo commented May 24, 2019

Interesting idea. It is currently not supported.

@vanlooverenkoen
Copy link
Contributor

This should really be added. Now we have to create extra objects because we had to use a crappy backend. Using a simple api to flatten your backend models

@jayden320
Copy link

I really need this feature. Is it supported now?

@vanlooverenkoen
Copy link
Contributor

Is there a roadmap for this feature? What timeframe could we expect for a P2?

@k-paxian
Copy link

k-paxian commented Dec 21, 2019

If you guys are still waiting for that feature, this library already has it implemented
https://github.com/k-paxian/dart-json-mapper#nesting-configuration

@KorbinianMossandl thank you for a great idea! This thing is called rfc6901

@vanlooverenkoen
Copy link
Contributor

Thanks. but I need to use json_serializable. Because I am using retrofit.dart that uses toJson and fromJson.

@kevmoo
Copy link
Collaborator

kevmoo commented Dec 23, 2019

PRs welcome here!

@NicolaVerbeeck
Copy link

I am working on an implementation for this.
Rough draft can be found here: https://github.com/Chimerapps/json_serializable/tree/feature/json_path

WIP, not ready for production

@mokai
Copy link

mokai commented Jan 3, 2020

Necessary function !

@taoyimin
Copy link

taoyimin commented Jan 3, 2020

I really need this feature!

@masewo
Copy link

masewo commented Mar 28, 2020

I forked @NicolaChimerapps fork and corrected two small errors:
https://github.com/masewo/json_serializable/tree/feature/json_path
For now it is working for me.

@kevmoo
Copy link
Collaborator

kevmoo commented Mar 28, 2020

@masewo and @NicolaChimerapps – I'll happily take a solid PR with testing, etc

@ouyanghuacom
Copy link

It's wishful for me.

@jeffaknine
Copy link

Any update on this ?

@miguelpruivo
Copy link

Bumping as this is a must have.

@kevmoo
Copy link
Collaborator

kevmoo commented Oct 23, 2020

Pull requests welcome – beyond the core features offered now, this package is a "beyond work hours" project.

@hacker1024
Copy link

hacker1024 commented Jan 1, 2021

If #783 gets merged, this will be possible, albeit in a convoluted manner:

@JsonSerializable()
class MyObject {
  @JsonKey(name: 'myRegularField')
  final String myRegularField;

  @JsonKey(extra: true)
  final String myNestedField;

  MyObject({
    required this.myRegularField,
    required this.myNestedField,
  });

  factory MyObject.fromJson(Map<String, dynamic> json) {
    return _$MyObjectFromJson(
      json,
      myNestedField: json['myInnerObject']['myNestedField'] as String,
    );
  }
  
  Map<String, dynamic> toJson() {
    final output = _$MyObjectToJson(this);
    output['myInnerObject'] = {'myNestedField': myNestedField};
    return output;
  }
}

kevmoo added a commit that referenced this issue Sep 24, 2021
Allows specifying an alternative constructor to invoke when creating a `fromJson` helper.

Closes #490
kevmoo added a commit that referenced this issue Sep 24, 2021
Allows specifying an alternative constructor to invoke when creating a `fromJson` helper.

Closes #490
@kevmoo kevmoo closed this as completed in 368a8c7 Sep 24, 2021
@NicolaVerbeeck
Copy link

How does 368a8c7 fix this?

@kevmoo
Copy link
Collaborator

kevmoo commented Sep 24, 2021

gah! Wrong issue!

@kevmoo kevmoo reopened this Sep 24, 2021
@ciriousjoker
Copy link

ciriousjoker commented Dec 13, 2021

Any news on this? It's marked as help wanted and there's an open PR related to it :/

@kevmoo
Copy link
Collaborator

kevmoo commented Dec 28, 2021

There is NOT an open PR on this. That was a mistake.

The issue here: we need some other syntax for key that's not a String because any String can be a valid key in a JSON map. So we'd need to support List<String> for key – or add another value. Both of which are quite a bit of work!

@ad-on-is
Copy link

There is NOT an open PR on this. That was a mistake.

The issue here: we need some other syntax for key that's not a String because any String can be a valid key in a JSON map. So we'd need to support List<String> for key – or add another value. Both of which are quite a bit of work!

How about something like

@JsonSerialiable(explicitJson: true, keySeparator: ">")


class Person {
@JsonKey(name: 'name>fist_name')
String name;
}

@kevmoo
Copy link
Collaborator

kevmoo commented Feb 3, 2022

After consideration, I've decided not to invest time here. It adds a LOT of complexity.

If you still want this feature, it's pretty easy to implement with a JsonConverter

See https://github.com/google/json_serializable.dart/blob/master/example/lib/nested_values_example.dart

@qevka
Copy link

qevka commented Feb 7, 2022

After consideration, I've decided not to invest time here. It adds a LOT of complexity.

If you still want this feature, it's pretty easy to implement with a JsonConverter

See https://github.com/google/json_serializable.dart/blob/master/example/lib/nested_values_example.dart

That would be nice if JsonConvert was actually working. I am having the same problem that is mentioned here: #1066

I tried downgrading my build_runner and json_annotation packages and also tried just using your code directly neither worked.

@Alameen688
Copy link

In my case I didn't need the toJson data to transform data back to the original structure I just needed to read the correct data and readValue worked perfectly fine in combination with deep_pick.

@JsonKey(readValue: readNestedItems)
List<NestedItem> nestedItems;
  static List<String, dynamic> readNestedItems(Map json, String key) {
    final fields = pick(json, key, 'items').asListOrEmpty(_yourFromPickFunction);
    return fields;
  }

@Veeksi
Copy link

Veeksi commented Apr 14, 2022

After consideration, I've decided not to invest time here. It adds a LOT of complexity.
If you still want this feature, it's pretty easy to implement with a JsonConverter
See https://github.com/google/json_serializable.dart/blob/master/example/lib/nested_values_example.dart

That would be nice if JsonConvert was actually working. I am having the same problem that is mentioned here: #1066

I tried downgrading my build_runner and json_annotation packages and also tried just using your code directly neither worked.

I am also having this exact same problem with the explicit json converter

@JPaulMora
Copy link

Chiming in to show support/need for this functionality.

@rignaneseleo
Copy link

Up

@EvGeniyLell
Copy link

EvGeniyLell commented Dec 21, 2023

I'm use next solution

@JsonKey(readValue: nestedReader, name: 'extras/apiKey') List<String>? extras,

where nestedReader is

Object? nestedReader(Map json, String key) {
  final keys = key.split('/');
  return _nestedReader(json, keys);
}

Object? _nestedReader(final Object? object, Iterable<String> keys) {
  if (keys.isEmpty || object == null) {
    return object;
  }
  if (object is Map) {
    final subObject = object[keys.first];
    final subKeys = keys.skip(1);
    return _nestedReader(subObject, subKeys);
  }
  if (object is List) {
    return object.fold<dynamic>([], (list, subObject) {
      return list..add(_nestedReader(subObject, keys));
    });
  }
  return object;
}

for this test

void main() {
  final Map map = {
    'extras': [
      {'apiKey': 1, 'name': 'a'},
      {'apiKey': 3, 'name': 'b'},
      {'apiKey': 5, 'name': 'c'},
      {'apiKey': 7, 'name': 'd'},
    ]
  };

  final result = nestedReader(map, 'extra/apiKey');
  print('result $result');
}

result will be

result (1, 3, 5, 7)


update:
also we can declare

class NestedJsonKey extends JsonKey {
  const NestedJsonKey({
    required super.name,
  }) : super(readValue: nestedReader);
}

and use it as

@NestedJsonKey(name: 'lastLocation/lng') double? test,

@devnta
Copy link

devnta commented Mar 11, 2024

There is no solution to this problem in 2024

@creativecreatorormaybenot

@phamquoctrongnta check 2dfffd0.

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

No branches or pull requests