I want to add new properties in JSON object.
I did the following to get my result.
In MapJson.vb Class
Public Class MapJson
Public Class item
Public Property ColList As ColMap
End Class
Public Class ColMap
Public Property inv As String
End Class
End Class`
In a winform button click:
Dim ColLst As New List(Of MapJson.ColMap)
Dim ColItem As New MapJson.ColMap With {
.inv = "ABC"
}
ColLst.Add(ColItem)
Dim YearItem As New MapJson.item With {
.ColList = ColLst.Single
}
Dim CreateNewJson As String = JsonConvert.SerializeObject(YearItem, Formatting.Indented)
MsgBox(CreateNewJson)
The result I get is:
{
"ColList": {
"inv": "ABC"
}
}
Now I want to add properties to ColList Object.
Properties can be anything so I can't predefine it in the class.
I want something Like this :
{
"ColList": {
"inv": "ABC",
"anyname1": "anyStringValue1",
"anyname2": "anyStringValue1",
"anyname3": "anyStringValue1"
}
}
I searched internet and found this.
Dim jo As JObject = JObject.FromObject(jsontext)
jo.Add("feeClass", "A")
jo.Add("feeClass1", "B")
jo.Add("feeClass2", "C")
jo.Add("feeClass3", "D")
MsgBox(jo.ToString)
This works properly but I don't know how to add it to the ColList Object.
Thank you for you help in advance. :)
If you know the property names ahead of time, you could just create an anonymous type to serialize:
Dim YearItem = New With {
.ColList = New With {
.inv = "ABC"
.anyname1 = "anyStringValue1"
.anyname2 = "anyStringValue1"
.anyname3 = "anyStringValue1"
}
}
Crucially, the first line of the code doesn't state MapJson.item etc, it just says New With {
You don't really need your classes with this, if all youre doing is creating them for serialization purposes, it's probably neater to just create an anonymous one
If you don't know them ahead of time, replace the ColMap with a dictionary:
Dim x = New With {
.ColList = New Dictionary(Of String, String)
}
x.ColList.Add("inv", "ABC")
x.ColList.Add("anyname1", "anyStringValue1")
x.ColList.Add("anyname2", "anyStringValue1")
x.ColList.Add("anyname3", "anyStringValue1")
Though this example doesn't demo that (clearly I do know them ahead of time because it wrote them into the code).. perhaps a loop that adds a list will be used in production
PS if youre desperate to keep those classes:
Public Class MapJson
Public Class item
Public Property ColList As Dictionary(Of String, String)
End Class
End Class`
Okay, I found it myself.
Posting here as there is less question related to this out there.
What I did is:
Suppose jsontext is what you got result at first, i.e
Say,
jsontext = "{
"ColList": {
"inv": "ABC"
}
}"
Later I did like this,
Dim NewJO As JObject = JObject.Parse(jsontext)
Dim NewSubJO As JObject = TryCast(NewJO("ColList"), JObject)
NewSubJO.Add("AA", "A")
NewSubJO.Add("BA", "B")
NewSubJO.Add("CA", "C")
MsgBox(NewJO.ToString)
And I got desired answer as
{
"ColList": {
"inv": "ABC",
"AA": "A",
"BA": "B",
"CA": "C"
}
}
I hope this helps to others :)
Related
I am using the Jackson library to convert Java objects to YAML format. Based on the documentation I found on the Internet, I was able to quickly write a function that does the conversion.
I am seeking to convert the following classes to YAML:
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
public class ParamInfo
{
private String paramName;
private String paramType;
// getters and setters
}
Using Jackson's ObjectMapper, I can easily generate the YAML:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory());
RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}
The YAML I get is below:
---
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
The YAML I get is OK, but it has some problems in my eyes. One probem is the "---" that it begins with. Another is the fact that I would like to be able to group the information in a manner similar to the YAML below:
RequestInfo:
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
All of the examples I am seeing on the Internet use an Employee class, and talk about how to convert that class to YAML, but do not tell how to avoid the "---" (or change it into soething more descriptive). I also cannot find anything that tells how to group the YAML in the manner I describe.
Does anyone know how to do this? Is there a way to eliminate the "---", or create a name (like "RequestInfo") that groups together the translated data in an object?
You can ignore --- by disable YAMLGenerator.Feature.WRITE_DOC_START_MARKER..
If you want to wrap value under class name then u need to use #JsonRootName...
Try with this:
RequestInof class:
#JsonRootName("RequestInfo")
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
Test:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
theMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}
The question being asked is as follows:
Implement the UniqueNames method. When passed two arrays of names, it will return an array containing the names that appear in either or both arrays. The returned array should have no duplicates.
For example, calling MergeNames.UniqueNames({'Ava', 'Emma', 'Olivia'}, {'Olivia', 'Sophia', 'Emma'}) should return an array containing Ava, Emma, Olivia, and Sophia in any order.
Starting Code:
Module Module1
Public Class MergeNames
Public Shared Function UniqueNames(names1() As String, names2() As String) As String()
Throw New NotImplementedException()
End Function
End Class
Public Sub Main()
Dim names1() As String = {"Ava", "Emma", "Olivia"}
Dim names2() As String = {"Olivia", "Sophia", "Emma"}
Console.WriteLine(string.Join(", ", MergeNames.UniqueNames(names1, names2))) ' should print Ava, Emma, Olivia, Sophia
End Sub
End Module
LINQ would be the easiest way to go here:
Dim combinedUniqueNames = names1.Union(names2).Distinct().ToArray()
Union will combine two lists, Distinct will remove duplicates and ToArray creates a new array from the result. As is pretty much always the case with LINQ extension methods, they can all be called on any IEnumerable(Of T). Your String arrays implement IEnumerable(Of String).
EDIT:
As per Jimi's comment, we just need:
Dim combinedUniqueNames = names1.Union(names2).ToArray()
I guess I should have realised, given that 'union' is a set operation and does exclude duplicates in a mathematical context.
import java.util.ArrayList;
import java.util.List;
public class MergeNames {
public static String[] uniqueNames(String[] names1, String[] names2) {
List<String> list= new ArrayList<String>();
for (String name: names1) {
if(!list.contains(name)) {
list.add(name);
}
}
for (String name: names2) {
if(!list.contains(name)) {
list.add(name);
}
}
String[] a= list.toArray(new String[list.size()]);
return a;
}
public static void main(String[] args) {
String[] names1 = new String[] {"Ava", "Emma", "Emma","Olivia"};
String[] names2 = new String[] {"Olivia", "Sophia", "Emma"};
System.out.println(String.join(", ", MergeNames.uniqueNames(names1, names2))); // should print Ava, Emma, Olivia, Sophia
}
}
I have a custom class declared in the module source code.
public class Friend{
public String name;
public List<String> phoneNumbers;
public List<String> emailAddresses;
public Friend(String name, List<String>emailAddresses,
List<String>phoneNumbers){
this.name = name;
this.emailAddresses = emailAddresses;
this.phoneNumbers = phoneNumbers;
}
}
I declared an Android Method in the Module
#Kroll.method
protected synchronized void getListOfObjects(){
List<String> emailAddresses = Arrays.asList("email1#yahoo.com", "email2#yahoo.com", "email3#yahoo.com");
List<String> phoneNumbers = Arrays.asList("1", "2", "3");
List<Friend> friendList = new ArrayList<Friend>();
friendList.add(new Friend("test1", emailAddresses, phoneNumbers));
friendList.add(new Friend("test2", emailAddresses, phoneNumbers));
friendList.add(new Friend("test3", emailAddresses, phoneNumbers));
KrollDict kd = new KrollDict();
kd.put("friendList", friendList);
if (hasListeners("onShow")) {
fireEvent("onShow", kd);
}
}
Upon Calling the getListOfOjects method in the Titanium App
module.getListOfObjects();
module.addEventListener('onShow', function(e){
Ti.API.info(JSON.stringify(e.friendList));
});
I cant seem to retrieve the friendList object.
The EXPECTED RESULT that I wanted to achieve would be like this
[
{test1, ["email1#yahoo.com", "email2#yahoo.com", "email3#yahoo.com"], ["1", "2", "3"]},
{test2, ["email1#yahoo.com", "email2#yahoo.com", "email3#yahoo.com"], ["1", "2", "3"]},
{test3, ["email1#yahoo.com", "email2#yahoo.com", "email3#yahoo.com"], ["1", "2", "3"]}
]
The question is, HOW TO ACHIEVE THE EXPECTED RESULT BASED ON THE SAMPLE CODES ABOVE?
Convert the List object into JSON string using GSON and assign the result string to the KrollDict property
KrollDict kd = new KrollDict();
Gson gson = new Gson();
String friendListStr = gson.toJson(friendList);
kd.put("friendList", friendListStr);
Another option is to return an object array like this:
KrollDict kd = new KrollDict();
Object[] obj = new Object[friendList.size()];
for (int i=0; i< friendList.size(); ++i){
KrollDict model = new KrollDict();
model.put("name", friendList.get(i).name);
// ...
obj[i] = model;
}
kd.put("list", obj);
fireEvent("onShow", kd);
That way you'll have an array in your event and don't need to convert that string into json later on.
If you want to use a JSON you can use TiConvert with toJSON, toJSONArray or toJSONString depending on your parameter. No need for Gson.
I am currently using the Newtonsoft framework to serialize my product categories dataset into json data.
The current way i do it is:
Public Function Category() As String
Try
Dim ds As DataSet = getDataSetFromPTLSAGE("website.CategoryList", db_conx("xxxxxxxxxxxx"))
Dim string_ As String
string_ = JsonConvert.SerializeObject(ds, Newtonsoft.Json.Formatting.Indented)
Return string_
Catch ex As Exception
Return ex.ToString
End Try
End Function
This works well and produces results like this:
{
"Table": [
{
"Id": "21",
"Name": "Accessories",
"URLFriendlyName": "accessories"
},
{
"Id": "06",
"Name": "Baby",
"URLFriendlyName": "baby"
},
{
"Id": "01",
"Name": "Bath & Shower",
"URLFriendlyName": "bath-shower"
},
{
"Id": "18",
"Name": "Books & Stationery",
"URLFriendlyName": "books-stationery"
}
]
}
Now what I would like to do is insert the sub categories into the json output. I can obtain the sub category data easily enough and put it into a dataset but what is the best method to have an array of objects inside the current object. The output should look like this:
{
"Table": [
{
"Id": "21",
"Name": "Accessories",
"URLFriendlyName": "accessories",
"SubCategory": [
{
"Id":"01",
"Name":"Travel",
"URLFriendlyName":"travel"
},
{
"Id":"02",
"Name":"Umbrella",
"URLFriendlyName":"umbrella"
}
]
}
]
}
Any thoughts and suggestions how i would serialise a linked datatable inside a dataset?
It was Carra's answer that lead me to this but in case anyone wants to see the final code:
Public Class Class1
Public Function Category() As String
Try
Dim _categorylist As New CategoryList
_categorylist.Categories = New List(Of Categories)
Dim ds As DataSet = getDataSetFromSQL("website.CategoryList", db_conx("xxxxxxxx"))
If ds.Tables(0).Rows.Count > 0 Then
For i = 0 To ds.Tables(0).Rows.Count - 1
Dim _category As New Categories
Dim id As String = ds.Tables(0).Rows(i)("Id").ToString.Trim
_category.Id = id
_category.Name = ds.Tables(0).Rows(i)("Name").ToString.Trim
_category.URLFriendlyName = ds.Tables(0).Rows(i)("URLFriendlyName").ToString.Trim
_category.SubCategories = New List(Of SubCategories)
Dim subDs As DataSet = getDataSetFromSQL("website.SubCategoryList", db_conx("xxxxxxxx"), "#id", id)
If subDs.Tables(0).Rows.Count > 0 Then
For x = 0 To subDs.Tables(0).Rows.Count - 1
Dim _subCategory As New SubCategories
_subCategory.Id = subDs.Tables(0).Rows(x)("Id").ToString.Trim
_subCategory.Name = subDs.Tables(0).Rows(x)("Name").ToString.Trim
_subCategory.URLFriendlyName = subDs.Tables(0).Rows(x)("URLFriendlyName").ToString.Trim
_category.SubCategories.Add(_subCategory)
Next x
End If
_categorylist.Categories.Add(_category)
Next
End If
Return JsonConvert.SerializeObject(_categorylist, Newtonsoft.Json.Formatting.Indented)
Catch ex As Exception
Return ex.ToString
End Try
End Function
End Class
Public Class CategoryList
Public Property Categories() As List(Of Categories)
End Class
Public Class Categories
Public Property Id() As String
Public Property Name() As String
Public Property URLFriendlyName() As String
Public Property SubCategories As List(Of SubCategories)
End Class
Public Class SubCategories
Public Property Id() As String
Public Property Name() As String
Public Property URLFriendlyName() As String
End Class
Please note that the function getDataSetFromSql is just a helper function I've created to help me quickly obtain stored procedure datasets from SQL
You can do it like this:
Create a class Table which contains id, name, urlfriendlyname and a List properties.
Convert your dataset to this table object.
Serialize this table object to json.
In C# when creating an object we can also (at the same time) fill out its properties. Is this possible in VB.NET?
For example:
MyObject obj = new MyObject
{
Name = "Bill",
Age = 50
};
Yes, it's possible:
Dim obj As New MyObject With { .Name = "Bill", .Age = 50 }
Two important things:
Use With keyword after class name and before { ... }
Property names have to be prefixed with a dot, so you have to use .Name instead of Name
For collection initializers use From keyword:
Dim obj as New List(Of String) From { "String1", "String2" }