I have this json structure from firebase where it's a list of objects but the root of each object is the ID
How can I serialize this to a list of object with the id/root as a member variable. This is for Spring boot so I would prefer if it were a Jackson2 solution.
This may be the same question as Jackson JSON key as value in Java but my answer is better because it doesn't require an extra/useless class
val reader = ObjectMapper().reader()
val tree = reader.readTree(testJson)
val eventList = mutableListOf<Event>()
tree.fields().iterator().forEach {
val event = Event(
it.key,
it.value.get("name").asText(),
it.value.get("description").asText(),
it.value.get("startDate").asText(),
it.value.get("startTime").asText(),
it.value.get("endDate").asText(),
it.value.get("endTime").asText(),
it.value.get("imageUrl").asText()
)
eventList.add(event)
}
I have found a solution using jackson in kotlin, it's not the prettiest but it works. the fields method returns a map of children. So, I am iterating through the map and adding the key as the object id member and then grabbing the rest of the data from the nested map.
Sorry, I am not a pro in Jackson. But there is a simple way to transform your object in JavaScript -- and perhaps this will lay the foundation for something that can be ported to Jackson (java?)
This is the convertData function that does the transform:
var convertData = function (d) {
var arr = [];
for(var prop in data)
{
var el = { "id": prop };
var otherprops = data[prop];
for(var otherprop in otherprops)
{
el[otherprop] = otherprops[otherprop];
}
arr.push(el);
}
return arr;
}
Tnis is what my sample data looks like after the conversion (slightly different values than yours):
[{"id":"-L8eoUd5mqJGnXDVSmb0","description":"With a great description","endDate":"12/31/2018","endTime":"03:00","imageUrl":"/favicon.ico","name":"Here's a Good Event","startDate":"12/01/2018","startTime":"12:00"},{"id":"-L8jO6Zhz976hvoLUiga","description":"Another item","endDate":"12/30/2018","endTime":"03:05","imageUrl":"/favicon2.ico","name":"Event #2","startDate":"12/11/2018","startTime":"12:03"}]
Link to JSFiddle: https://jsfiddle.net/2t1s2are/13/
Hope this helps!!
Related
Sorry but I didn't explain it very well. I edit my question again:
I have an angular 4 application and I use json2typescript to convert from json to object and vice versa but I have a problem because I have a class structure and the response json from an external api has another structure. Example:
Customer {
#JsonProperty('idCardNumber', String)
idCardNumber: string = undefined;
#JsonProperty('rolInfo.name',String)
name: string = undefined;
#JsonProperty('rolInfo.surname',String)
surname: string = undefined;
}
External Json API Reponse:
{
"idCardNumber": "08989765F",
"rolInfo": {
"name": "John"
"surname: "Smith"
}
}
So, I would like to map from the json above to my Customer object and not to change my structure. I tried to put 'rolInfo.name' into the JsonProperty, but that doesn't work.
Change your Customer class to something like below
Customer {
#JsonProperty('idCardNumber', String)
idCardNumber: string = undefined;
#JsonProperty('rolInfo', Any)
rolInfo: any = {}; // if you set this to undefined, handle it in getter/setter
get name(): string {
return this.rolInfo['name'];
}
set name(value: string) {
this.rolInfo['name'] = value;
}
get surname(): string {
return this.rolInfo['surname'];
}
set surname(value: string) {
this.rolInfo['surname'] = value;
}
}
That should do it
Seems like the response JSON is already in a good format and you don’t need to do the conversion.
I would recommend creating models as they allow for serialization and deserialization when making API calls and binding the response to that model.
I'm pulling a JSON request from the politifact API:
request('http://politifact.com/api/v/2/statement/?format=[JSON]&order_by=-ruling_date&limit=1')
.then(({
data
}) => {
newArticles = extractListingsFromJSON(data);
and parsing it with a function that the JSON is passed to
function extractListingsFromJSON(json) {
var jsonObject = json.objects
Outputs entire objects array
var headline = jsonObject[0].facebook_headline
console.log("headline:\n" + headline)
Outputs headline from Objects[0]
This works as intended. However, when I try to iterate through the objects array like so:
for (var attr in jsonObject) {
console.log(attr+": "+jsonObject.facebook_headline);
}
Outputs "0: undefined"
I also tried:
console.log(attr+": "+jsonObject[facebook_headline];
Outputs nothing
As you mentioned yourself jsonObject is an array.
json.objects.forEach(function (i) {
console.log(i.facebook_headline)
})
You still need the attr key to iterate through the jsonObject. Try doing attr+" :"+jsonObject[attr].facebook_headline
instead.
I want to get my C#7 tuple property names in my JSON (Newtonsoft.Json) output.
My problem is:
When I want to convert my tuple to JSON format that not support my parameters names.
For example this is my "Test2" method and you can see the JSON output:
public void Test2()
{
var data = GetMe2("ok");
var jsondata = JsonConvert.SerializeObject(data);//JSON output is {"Item1":5,"Item2":"ok ali"}
}
public (int MyValue, string Name) GetMe2(string name)
{
return (5, name + " ali");
}
The JSON output is "{"Item1":5,"Item2":"ok ali"}" but i want "{"MyValue":5,"Name":"ok ali"}";
This is not impossible because I can get property names in runtime:
foreach (var item in this.GetType().GetMethods())
{
dynamic attribs = item.ReturnTypeCustomAttributes;
if (attribs.CustomAttributes != null && attribs.CustomAttributes.Count > 0)
{
foreach (var at in attribs.CustomAttributes)
{
if (at is System.Reflection.CustomAttributeData)
{
var ng = ((System.Reflection.CustomAttributeData)at).ConstructorArguments;
foreach (var ca in ng)
{
foreach (var val in (IEnumerable<System.Reflection.CustomAttributeTypedArgument>)ca.Value)
{
var PropertyNameName = val.Value;
Console.WriteLine(PropertyNameName);//here is property names of C#7 tuple
}
}
}
}
dynamic data = attribs.CustomAttributes[0];
var data2 = data.ConstructorArguments;
}
}
For the specific case here, it is impossible. That's because SerializeObject has no way of finding out where the tuple came from, all it sees is ValueTuple<int, string>.
The situation would be different if you were serializing an object with tuple properties, in which case SerializeObject could use reflection to find the TupleElementNames attributes (even though it currently doesn't).
The short answer it that tuples don't have properties.
A tuple is a bag of values used, mainly, to return multiple values from a method.
They were never intended to model entities.
The only way to solve your problem, if you don't want to create a type for that, is:
public void Test2()
{
var data = GetMe2("ok");
var jsondata = JsonConvert.SerializeObject(new { data.MyValue, data.Name });//JSON output is {"Item1":5,"Item2":"ok ali"}
}
I have a model with a hasMany realtionship.
I currently use the EmbeddedRecordsMixin to include the JSONAPI in my payload that is then sent to the server.
My problem is that I wish to send only the JSON representation of this object. i.e without type and attributes hash. Instead I wish to the send the payload as simply JSON { id: 1, Name: 'Darren', Surname: 'Blh' ... }
How is it possible to convert the JSONAPI to JSON?
Thanks
Darren
I solved this by overriding the serialize() method on the serializer.
serialize(snapshot, options) {
var json = this._super(...arguments);
for (let i = 0; i < json.passengers.length; i++ ) {
console.log('Converting Person JSON:API to JSON');
json.passengers[i].id = json.passengers[i].data.id;
json.passengers[i].firstName = json.passengers[i].data.attributes.firstName;
json.passengers[i].lastName = json.passengers[i].data.attributes.lastName;
delete json.passengers[i].data;
}
return json;
}
I would like to read a dynamic object from a json file and then use this in a stringTemplate.
The following code works.
dynamic data = new { bcName = "Lixam B.V", periodName = "July 2013" };
var engine = new Template("<m.bcName> <m.periodName>");
engine.Add("m", data);
engine.Render().Should().Be("Lixam B.V July 2013");
The following code fails
var json = "{bcName : 'Lixam B.V', periodName : 'July 2013'}";
dynamic data = JsonConvert.DeserializeObject(json);
string name = (data.bcName);
name.Should().Be("Lixam B.V"); // this passes
var engine = new Template("<m.bcName> <m.periodName>");
engine.Add("m", data);
engine.Render().Should().Be("Lixam B.V July 2013"); //fails
Is there another way to configure JsonConverter to be compatible with StringTemplate
You need to create an IModelAdaptor for whatever the compiled type representing dynamic is, and register it using TemplateGroup.RegisterModelAdaptor.
Inspired on Mr. Harwell's answer, I've implemented an IModelAdaptor that enable the usage of Newtonsoft.Json parsed objects.
Here it goes:
internal class JTokenModelAdaptor : Antlr4.StringTemplate.IModelAdaptor
{
public object GetProperty(
Antlr4.StringTemplate.Interpreter interpreter,
Antlr4.StringTemplate.TemplateFrame frame,
object obj,
object property,
string propertyName)
{
var token = (obj as JToken)?.SelectToken(propertyName);
if (token == null)
return null;
if (token is JValue)
{
var jval = token as JValue;
return jval.Value;
}
return token;
}
}
You just need to register the adaptor in your template group, like this:
template.Group.RegisterModelAdaptor(typeof(JToken), new JTokenModelAdaptor());