Angular 8 JSON.parse not parsing completely/impartially - json

I receive a JSON object that looks like this:
this data is being passed through a Socketio emit, so the angular HttpClient is not intercepting it.
{
"single":[
{
"name":"Xavi555",
"data":[
{
"_id":"5e2ea609f8c83e5435ebb6e5",
"id":"test1",
"author":"someone",
"recipient":"someone",
"content":"test",
"msgId":"Testid",
"gNamespace":""
}
]
}
],
"group":[]
}
however when I use JSON.parse() on the object above The key data does not contain the value of data that is to say:
private func(jsonObj: string): void {
console.log(jsonObj);
}
I see:
single: Array(1)
groups: Array(0)
single Array(1)
name: test
data: Array(0)
I thought it was an issue with deep cloning, but, when trying to do JSON.parse(JSON.stringify(jsonObj)) it returns the original json string object.
related but no solution posted
actual code:
private handleStoredMessages(dirtyObj: string): void {
// debugger;
const cleanObj = JSON.parse(dirtyObj);
const { single, group } = cleanObj;
console.log('raw json', dirtyObj);
onsole.log('clean json', cleanObj);
}
any ideas?

If you are using angular, then I doubt you should be using JSON.parse. This is handled by the HttpClient. Nevertheless, your assumption about your data structure is wrong. The single is an array of objects, not an object itself:
So to access the .data you need to do jsonObj.single[0].data. Which in itself is an array again
The only other reason this could happen, is because you modify the object/array somewhere else in your code, before you actually press the triangle in console to open the object. Hover on the blue information icon to see why.
Value below was evaluated just now
The object is lazily evaluated, meaning that if you did any transformations to the object, it will show that state, not the state at the moment you logged the object.

The issue of this was that the back end guy double encoded and did some weird stuff not my fault

Related

Json manipulation TypeScript Angular 2

I come from a Python Background and recently started programming using TypeScript and Angular2. I want to know how to obtain keys from a JSON object using TypeScript.
I have a response like so:
response.text()
I pass this object to a function
removeMetaData (my_data: string){
//(Various manipulation)...etc
}
i have read that I can call a json() method instead of text(). If I do that, what is the type I should use for my_data?
Then,
If my JSON looks like this:
{
"count": 100,
"next_page": "http://www.test.com/users/?page=2",
"prev_page": "http://www.test.com/users/?page=3",
"results":[
{
"username": "johnny"
},
Etc....
]
How do I parse that?
I've read I might have to use an interface but I don't understand how.
In python it's just response["next_page"] to get the key of a dictionary, then I can assign that value to a variable within the class. That is exactly what I'm trying to achieve within a component.
Thank you.
ADDITION
list() {
this.requestService.get(this.api_path)
.subscribe(
response => this.populate(response.json()),
error => this.response = error.text()
)
}
populate(payload: object) {
this.count = payload.count;
this.next = payload.next;
this.previous = payload.previous;
*payload.results => this.users = payload.results;******
}
Declare an interface which will be used as value object.
export interface IPage
{
count:number;
next_page:string;
prev_page:string;
results:Array<any>;
...
...
}
var my_data:IPage;
Now assign parsed json value to my_data and access all the properties with '.' operator i.e. my_data.count, my_data.results.
Feel free to throw any question.
If I do that, what is the type I should use for my_data?
Its just a javascript object.
As an example if you json looks like:
{
"foo": {
"bar": "bas"
}
}
Then in the parsed json (in variable someObj) the value someObj.foo.bar would be bas 🌹

Grails: Easy and efficient way to parse JSON from a Request

Please pardon me if this is a repeat question. I have been through some of the questions/answers with a similar requirement but somehow got a bit overwhelmed and confused at the same time. My requirement is:
I get a JSON string/object as a request parameter. ( eg: params.timesheetJSON )
I then have to parse/iterate through it.
Here is the JSON that my grails controller will be receiving:
{
"loginName":"user1",
"timesheetList":
[
{
"periodBegin":"2014/10/12",
"periodEnd":"2014/10/18",
"timesheetRows":[
{
"task":"Cleaning",
"description":"cleaning description",
"paycode":"payCode1"
},
{
"task":"painting",
"activityDescription":"painting description",
"paycode":"payCode2"
}
]
}
],
"overallStatus":"SUCCESS"
}
Questions:
How can I retrieve the whole JSON string from the request? Does request.JSON be fine here? If so, will request.JSON.timesheetJSON yield me the actual JSON that I want as a JSONObject?
What is the best way to parse through the JSON object that I got from the request? Is it grails.converters.JSON? Or is there any other easy way of parsing through? Like some API which will return the JSON as a collection of objects by automatically taking care of parsing. Or is programatically parsing through the JSON object the only way?
Like I said, please pardon me if the question is sounding vague. Any good references JSON parsing with grails might also be helpful here.
Edit: There's a change in the way I get the JSON string now. I get the JSON string as a request paramter.
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON) // No problem here. Returns a JSONObject. I checked the class type.
def jsonArray = jsonArray.timesheetList // No problem here. Returns a JSONArray. I checked the class type.
println "*** Size of jsonArray1: " + jsonArray1.size() // Returns size 1. It seemed fine as the above JSON string had only one timesheet in timesheetList
def object1 = jsonArray[1] // This throws the JSONException, JSONArray[1] not found. I tried jsonArray.getJSONObject(1) and that throws the same exception.
Basically, I am looking to seamlessly iterate through the JSON string now.
I have wrote some code that explains how this can be done, that you can see below, but to be clear, first the answers to your questions:
Your JSON String as you wrote above will be the contents of your POST payload to the rest controller. Grails will use its data binding mechanism to bind the incomming data to a Command object that your should prepare. It has to have fields corresponding to the parameters in your JSON String (see below). After you bind your command object to your actual domain object, you can get all the data you want, by simply operating on fields and lists
The way to parse thru the JSON object is shown in my example below. The incomming request is esentially a nested map, with can be simply accessed with a dot
Now some code that illustrates how to do it.
In your controller create a method that accepts "YourCommand" object as input parameter:
def yourRestServiceMethod (YourCommand comm){
YourClass yourClass = new YourClass()
comm.bindTo(yourClass)
// do something with yourClass
// println yourClass.timeSheetList
}
The command looks like this:
class YourCommand {
String loginName
List<Map> timesheetList = []
String overallStatus
void bindTo(YourClass yourClass){
yourClass.loginName=loginName
yourClass.overallStatus=overallStatus
timesheetList.each { sheet ->
TimeSheet timeSheet = new TimeSheet()
timeSheet.periodBegin = sheet.periodBegin
timeSheet.periodEnd = sheet.periodEnd
sheet.timesheetRows.each { row ->
TimeSheetRow timeSheetRow = new TimeSheetRow()
timeSheetRow.task = row.task
timeSheetRow.description = row.description
timeSheetRow.paycode = row.paycode
timeSheet.timesheetRows.add(timeSheetRow)
}
yourClass.timeSheetList.add(timeSheet)
}
}
}
Its "bindTo" method is the key piece of logic that understands how to get parameters from the incomming request and map it to a regular object. That object is of type "YourClass" and it looks like this:
class YourClass {
String loginName
Collection<TimeSheet> timeSheetList = []
String overallStatus
}
all other classes that are part of that class:
class TimeSheet {
String periodBegin
String periodEnd
Collection<TimeSheetRow> timesheetRows = []
}
and the last one:
class TimeSheetRow {
String task
String description
String paycode
}
Hope this example is clear enough for you and answers your question
Edit: Extending the answer according to the new requirements
Looking at your new code, I see that you probably did some typos when writting that post
def jsonArray = jsonArray.timesheetList
should be:
def jsonArray = jsonObject.timesheetList
but you obviously have it properly in your code since otherwise it would not work, then the same with that line with "println":
jsonArray1.size()
shuold be:
jsonArray.size()
and the essential fix:
def object1 = jsonArray[1]
shuold be
def object1 = jsonArray[0]
your array is of size==1, the indexing starts with 0. // Can it be that easy? ;)
Then "object1" is again a JSONObject, so you can access the fields with a "." or as a map, for example like this:
object1.get('periodEnd')
I see your example contains errors, which lead you to implement more complex JSON parsing solutions.
I rewrite your sample to the working version. (At least now for Grails 3.x)
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON)
println jsonObject.timesheetList // output timesheetList structure
println jsonObject.timesheetList[0].timesheetRows[1] // output second element of timesheetRows array: [paycode:payCode2, task:painting, activityDescription:painting description]

Json.Net boolean parsing issue

JObject.Parse(jsonString) is causing issue for boolean data. e.g. The json is :
{
"BoolParam": true
}
I used the following code to parse:
JObject data = JObject.Parse(str1);
foreach (var x in data)
{
string name = x.Key;
Console.Write(name + " (");
JToken value = x.Value;
Console.Write(value.Type + ")\n");
Console.WriteLine(value);
}
This print out the value as :
BoolParam (Boolean) : True
The case sensitivity causes issue as I save this json for later use. The saved json looks like
{
"BoolParam": True
}
However, when i later use it, the JObject.Parse(str) throws error as invalid Json :Unexpected character encountered while parsing value: T. Path 'BoolParam', line 2, position 15.
If I change the case from "True" to "true", it works. I dont want to add this hack to change the case when saving but is there a better way to handle this scenario.
I dont want to add this hack to change the case when saving but is
there a better way to handle this scenario.
No, you have to produce valid JSON when saving if you want to be able to later deserialize it with a JSON serializer such as Newtonsoft JSON. So fixing your saving routing is the right way to go here.
One could use anonymous types and no worry about case sensitivity of boolean type variables
public static void Main()
{
bool a = true;
JObject c = JObject.FromObject(new {BoolParam= a});
Console.WriteLine(c);
}
Output:
{
"BoolParam": true
}

Backbone.js .save() JSON response attribute issue

So my issue is this.
Using backbone to save something in a MYSQL Database.
When I call this.model.save() I am getting a very weird issue.
The model will save the JSON response as an object and will not update the new values instead.
So my attributes in development tools will look something like this.
attributes: Object
0: Object
ID: "4"
Name: "TEST"
Title: "MEOW"
Stuff: "1"
When: "2013-02-14 22:17:14"
The 0 should not be there. I did confirm that the json object is valid so I know that is not the issue here.
It looks like your JSON response is actually an array with a single element, not an object.
The property 0 is created when Backbone calls model.set(response), which in turn copies all keys of the response object to the attributes hash. If an array is passed to set, this is what happens.
You should fix your server to respond with a raw object ({...}) instead of an array ([{...}]). If you're not able to change the server behaviour, you can override Model.parse to unwrap the response on the client:
var Model = Backbone.Model.extend({
parse: function(response) {
return _.isArray(response) ? response[0] : response;
}
});

Is there a way to add an additional field to Grails JSON response?

I want every JSON response to post-request to contain a field success. What's the best way to add this field there?
I use code like this to generate JSON responses:
try {
def entity = myService.saveEntity(arg1,arg2)
render entity as JSON //I want to add artificial field 'success = "yes"' here
} catch (ValidationException e) {
render parseErrors(e.errors) as JSON //field 'success = "no"' here
}
I just struggled with this exact issue this week. I wanted to send back a domain class as JSON but at the same time add an 'errorMessage' property that would potentially contain additional information.
Turns out that when using as JSON in grails it sends back a converter object, but its possible to turn that converter instance into a jsonObject using JSON.parse() which we can easily add new values to.
def jsonObject = JSON.parse((entity AS JSON).toString())
jsonObject.put("success", "yes")
render jsonObject as JSON
I think there are a couple of different approaches but this ended up being the easiest for me since I already have custom converters for most of my domain classes and I didn't want to add any other transient properties to my domain object.
Could you return a map containing the success field, and the object wrapped inside a separate variable:
try {
def entity = myService.saveEntity(arg1,arg2)
render [ success:'yes', val:entity ] as JSON
} catch (ValidationException e) {
render [ success:'no', val:parseErrors(e.errors) ] as JSON
}
Not tested it mind...
You can register your own JSON marshaller (at BootStrap.groovy, for example), like:
JSON.registerObjectMarshaller(MyEntity) { MyEntity it ->
return [
someField : it.someField, // you should specify fields for output, or put all '.properties'
success : true // as I understand you always have 'true' for real entity
]
}
where MyEntity is your class you want to use