This is the problem that I'm trying to resolve. I have a list of map that I want to convert into JSON array in Groovy.
The list is:
List<Map<String, String>> studentList = [{id=1,name=John,email=john#google.com},{id=2,name=Peter,email=peter#google.com},{id=3,name=James,email=james#google.com}]
Desired JSON output is:
{
students: [{
"id" = "1",
"name" = "John",
"contact": {
"email": "john#google.com"
}
}, {
"id" = "2",
"name" = "Peter",
"contact": {
"email": "peter#google.com"
}
}, {
"id" = "3",
"name" = "James",
"contact": {
"email": "james#google.com"
}
}
]
}
My code only generates 1 student. Can anyone help me please?
def builder = new JsonBuilder()
for (Map student: studentList) {
builder.students {
id student.id
name student.name
contact {
email student.email
}
}
}
println builder.toPrettyString()
Appreciate your time and advice. Thank you.
Pass a list to the builder
You don't need to iterate through the list, you can pass a list to the builder,
using JsonBuilder's implicit call() method.
def builder = new JsonBuilder()
builder {
students builder( studentList )
}
public Object call( List list )
A list of elements as arguments to the JSON builder creates a root JSON array
See the JsonBuilder Groovydoc page for details of the various call()
methods.
Example code
In this example I've fixed up your map, and introduced a small Student class, to
simplify the code.
import groovy.json.JsonBuilder
class Student { int id; String name; String email }
studentList = [
new Student( id:1, name:'John', email:'john#google.com' ),
new Student( id:2, name:'Peter', email:'peter#google.com' ),
new Student( id:3, name:'James', email:'james#google.com' )
]
def builder = new JsonBuilder()
builder {
students builder( studentList )
}
println builder.toPrettyString()
Resulting JSON
{
"students": [
{
"id": 1,
"email": "john#google.com",
"name": "John"
},
{
"id": 2,
"email": "peter#google.com",
"name": "Peter"
},
{
"id": 3,
"email": "james#google.com",
"name": "James"
}
]
}
I have solved it with ff code.
def students = []
def builder = new JsonBuilder()
for (Map student: studentList) {
builder {
id student.id
name student.name
contact {
email student.email
}
}
students.add(builder.toString())
}
def jsonSlurper = new JsonSlurper()
def items = jsonSlurper.parseText(students.toString())
def json = new JsonBuilder()
json "students": items
println json.toPrettyString()
Related
This is the response I am getting from server. All the properties are String and int expect data. It is a list of objects. When serializing the response it shows error. Please explain what is wrong with my code. I am from javascript background. Serialization in flutter is different from javascript.
class ResponseModel {
String image;
int row;
int column;
int position;
List<Data> data;
ResponseModel({this.image, this.row, this.column, this.position});
factory ResponseModel.fromJson(Map<String, dynamic> parsedJson) {
return ResponseModel(
image: parsedJson['image'],
row: parsedJson['row'],
column: parsedJson['column'],
position: parsedJson['position'],
);
}
}
class Data {
String imageUrl;
Data({this.imageUrl});
factory Data.fromJson(Map<String, dynamic> parsedJson) {
return Data(imageUrl: parsedJson["imageUrl"]);
}
}
[
{
"type": "image",
"row": 1,
"column": 3,
"position":"1",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/6dad06016c6ab319.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/9ad209b0fc3d03e4.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/276/294/image/405e10d01fae5aa5.jpg?q=90"
}
]
},
{
"type": "image",
"row": 1,
"column": 2,
"position":"3",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/414/630/image/f186565389063212.jpg?q=90"
},
{
"imageUrl": "https://rukminim1.flixcart.com/flap/414/630/image/3eda035d946b0ebf.jpg?q=90"
}
]
},
{
"type": "image",
"row": 1,
"column": 1,
"position":"2",
"data": [
{
"imageUrl": "https://rukminim1.flixcart.com/flap/1187/636/image/4436d492e2563998.jpg?q=90"
}
]
}
]
Future<dynamic> getData() async {
final response = await http.get("https://api.myjson.com/bins/1g4o04");
final parsedJson = json.decode(response.body);
final finalResponse = ResponseModel.fromJson(parsedJson);
print(finalResponse);
setState(() {
data = parsedJson;
});
}
Error image
You can use this tool and select dart Language
Its because the response is a JSON array. Which means json.decode(response.body) returns a List<dynamic> and hence the variable parsedJson is List.
You're trying to pass this List as a parameter to the ResponseModel.fromJson(Map<String, dynamic>) method which accepts a Map as the parameter.
In simple words, you're trying to pass a List where a Map is expected.
Future<dynamic> getData() async {
final response = await http.get("https://api.myjson.com/bins/1g4o04");
final parsedJson = json.decode(response.body);
List<ResponseModel> responseList = <ResponseModel>[];
parsedJson.foreach((element) {
responseList.add(ResponseModel.fromJson(element));
})
///Response list will have your data
print(responseList);
}
Your code should be something like this
I am getting 90 cent success with my approach but when the response has got multiple entries in one of the child key then the logic gets failed and I am not able to put one common logic in place which would run for all the cases.
The response sample is
{
"items": [
{
"id":1,
"name": "John",
"sections": [
{
"id":1,
"description": "John smith"
}
]
}
]
}
Now my use case says you search for John text and then items array would contains many objects whose items.name or items.sections.description should contains the "John" keyword
The matching logic which I have put is working fine because I am iterating through items[].name and items.sections[].description
The main challenge comes when the sections[*].description contains the multiple sections like below
{
"items": [
{
"id":1,
"name": "John",
"sections": [
{
"id":1,
"description": "John smith"
},
{
"id":1,
"description": "remain smith of the first object"
}
]
}
]
}
The logic should now work on
items[].name or items.sections[].description (multiple entries of sections[*].description)
Problem I am facing is when I am iterating items[].name & items[].sections[*].description
It gives me all the names and all the sections.description in separate arrays what I want is that it should give me one by one.
For example first result set should give me below
[
"John"
]
and
[
"John smith"
"remain smith of the first object"
]
So that I can run my existing logic to check whether John is available or not. Currently my logic runs on first entry of the description and it does not check the next entry or section.description that is the reason below matching object is failing because "john" is present in the second entry of the description
{
"items": [
{
"id":11,
"name": "SMITH",
"sections": [
{
"id":11,
"description": "SMITH"
},
{
"id":11,
"description": "JOHN Carter"
}
]
}
]
}
The matching logic which I am currently using is -
* def matchText =
"""
function (nameArr, sectionArr, matchingWord)
{
for(var i = 0; i < nameArr.length; i++)
var regEx = new RegExp(matchingWord, 'gi')
var nameMatch = nameArr[i].match(regEx)
var secMatch = sectionArr[i].match(regEx)
if (nameMatch ==null && secMatch == null) {
return false;
}
}
return true;
}
"""
* def getName = get response.items[*].name
* def getDescription = get response.items[*].sections[*].description
* assert matchText(getName,getDescription,'john')
So this logic works when you have same length in name & sections.description but when sections.description has got multiple arrays then it does not iterate correctly. That was the only reason I wanted to treat the name as one object and sections.description as another even when there will be multiple child ids in it.
Sample Code:
Feature: Validation
Scenario:
* def resp =
"""
{
"items": [
{
"id": 11,
"name": "JOHN",
"sections": [
{
"id": 11,
"description": "SMITH"
},
{
"id": 11,
"description": "JOHN Carter"
}
]
}
]
}
"""
* def names = []
* def fun =
"""
function(x){
var json = x.sections;
var temp = x.name
for(var i = 0; i < json.length; i++) {
var obj = json[i];
temp = temp + "," + obj.description
}
karate.appendTo(names, temp);
}
"""
* def items = get resp.items[*]
* karate.forEach(items, fun)
* match each names == '#regex .*JOHN.*'
I am new to React-Native i am building a sample app, But i ha d small problem with this.state.array , I want a particular element value from array
my array is
this.state.userDetail: [
Object {
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
````````````````````````````````````````
In the above array i want user_id value ,
i tried different methods like
```````````````````````````
this.setState({ user_id: this.state.user_Details.user_id })
const item_id = this.state.user_Details.map((item) => { item.user_id });
var item_id = this.state.user_Details.filter(userDetails => { return userDetails[7]; })
``````````````````````````````````````````
but nothing will work i want only user_id value to update the users table , So please any help ..
If you wish to extract the user_id SPECIFICALLY from this example:
[
{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
and assuming this data is in your this.state.userDetail property.
The only thing you need is:
this.state.userDetail[0].user_id
Why this might not be working for you:
this.state.userDetail: [
Object { /// What's Object?
And if you are trying to parse more than 1 entry in the array unlike your example, you first need to select a certain entry with a 'for' loop or a .map() function.
I think you want to get one index user id, so I give the following code:
// define it in the constructor, and it may have more than one items
this.state.userDetail: [
{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
let userIdsArray = copyUserDetail.map((item) => { return item.user_id });
let itemId = userIdsArray[0]
console.log("the first user Id is",itemId)
// if you only want to the user_id, you can directly copyUserDetails[0].user_id
let userId = copyUserDetails[0].user_id
console.log("the first user Id is ==> ",userId)
this.setState({ user_id: itemID })
// the filter is accordng some condtion to return a new arry
let itemFilterArray = copyUserDetails.filter((element,i) => {
// filter the item which match some condition, for example the uerId not equal
//0
if(element.user_id !== 0){
return element
}
})
according to your require, I give the following code:
//if you do not have many userInfo
constructor(props){
super(props)
this.state= {
user_Details: {
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
}
}
// somewhere you want the userId
getUserId = () => {
return this.state.user_Details.user_id
}
}
//if you have many userinfo
constructor(props){
super(props)
this.state= {
user_Details: [{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
}]
}
// somewhere you want the some index userId
getUserId = (index) => {
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
return copyUserDetails[index].user_id
}
//somwhere you want all the userId
getUserId = () => {
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
let userIdArray = copyUserDetail.map((item) => { return item.user_id });
return userIdArray
}
}
and I suggest you can read the api about json and array
I need to create multiple Json arrays at a single instance. I have 38 rows. For 38 rows first I need to create 38 empty JSON arrays. Then in each JSON array i need to add first column of row as first object in all the arrays. Second column as 2nd object etc. Is there a way to specify the position to add the objects in each array?
[
[
{
"fileName": "123"
},
{
"id": "100"
},
{
"product": ""
}
],
[
{
"fileName": "123"
},
{
"id": "100"
},
{
"product": ""
}
]...38
]
package emp;
import javax.lang.model.element.PackageElement;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Temp
{
public static void main(String[] args) throws JSONException {
JSONArray jsonArray = new JSONArray();
jsonArray.put(createJsonArray("name 1", "id 1", "product 1"));
jsonArray.put(createJsonArray("name 2", "id 2", "product 2"));
jsonArray.put(createJsonArray("name 3", "id 3", "product 3"));
System.out.println(jsonArray.toString());
}
public static JSONArray createJsonArray(String name, String id, String product) throws JSONException
{
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileName", "123");
jsonArray.put(jsonObject);
jsonObject.put("id", "123");
jsonArray.put(jsonObject);
jsonObject.put("product", "product");
jsonArray.put(jsonObject);
return jsonArray;
}
}
May i know how to get JSON object from an json array??
JSON:
[
{
"id": 1,
"user": {
"id": 20710,
"username": "abc",
"first_name": "",
"last_name": "",
},
"action": {
"name": "xxx",
"date": 19/01/01,
},
},
{
"id": 2,
"user": {
"username": "xyx",
"first_name": "xxx",
"last_name": "yyy",
},
"action": {
"name": "xxx",
"date": 19/05/01,
},
},]
I want to get username of these users in a list, but i cant get the value when i get this json from api as JSONArray.
My code:
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
Log.d("Create Response", response.toString());
ArrayList<String> list = new ArrayList<String>();
JSONArray jsonArray = response;
try {
if (jsonArray != null) {
int len = jsonArray.length();
for (int i=0;i<len;i++){
JSONObject c=response.getJSONObject(1);
String id = c.getString(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put("id", id);
feeds_List.add(map);
}
}
I cannot use
JSONObject object=JsonArray.getJSONObject("user");
here,
it only accept int for getJSONObject("user"); if it is JSONArray
You can use like this also.Suppose response String is userInfo
ArrayList<String> usernames = new ArrayList<String>();
JSONArray userList = new JSONArray(userInfo);
for (int j = 0; j < userList.length(); j++) {
JSONObject userObject = new JSONObject(userList.getString(j));
String user = userObject.getString("user");
JSONObject usernameInfo = new JSONObject(user);
usernames.add(usernameInfo.getString("username"));
}
Try this, if not working please mention me in comment.