unable to correctly map json to data model - javascript

I want to model the following information into json but am unable to do so.
The server sends result of an operation to the client using the following model
class Result (result:string, additional-info:string)
additional-info could contain a json or a string depending on the use case. Thus its type is String. When I need to send a json in it, I simply send a string with a valid json syntax and I suppose the the Angular client would be able to convert the string into a json using JSON.parse.
The json I want to send to the client looks like
{
"result": "success",
"additional-info": {
"list ": [{
"tag": "sometag",
"description": "some description"
}]
}
}
I checked on jsonlint (https://jsonlint.com/) that the structure is correct.
On the client side (Angular), I am handing the message as follows:
getQuestions(some args){
console.log('response from server:',res)
console.log('response body',res.body)
let jsonResponse:ServerResponseAPI = res.body //should contain result and additional info
console.log("result: "+jsonResponse.result+", additional info:"+jsonResponse.additionalInformation)
let jsonList:string = jsonResponse.additionalInformation
console.log("jsonQuestionList: "+jsonList)
let information:Information = JSON.parse(jsonList)
console.log("information:"+information)
});
}
ServerResponseAPI is defined as
export class ServerResponseAPI{
constructor ( public result:string,
public additionalInformation:string){}
}
When I execute the code, I see the following prints on browser's console but I see that error that additional-info is not define.
response body {result: "success", additional-info: "{"list ": [{"tag": "sometag", "description": "some description"}]}"}
list-management.service.ts:46 result: success, additional info:undefined
I can see that the body contains result and additional-info but after casting the body to ServerResponseAPI, I see that result is success but additional-info is undefined.

in res.body, javascript creates an object
{
"result": "success",
"additional-info": {
"list ": [{
"tag": "sometag",
"description": "some description"
}]
}
}
The object has two keys - result and additional-info. Lets call it Object1
I assign it to an object which has keys result and additionalInfo. Note the difference in naming convention in additionalInfo. In javascript, names of variables are case sensitive, so the above two are different. Lets call this object2
Now result from object1 gets assigned to result from object2 because the keys match (same name result)
additional-info becomes a new key in the object2
additionalInfo key of object2 stays undefined as no key from object1 maps to additionalInfo
To solve the issue, I had to create a additional-info key ServerResponseAPI (alternatively I could have also changed my JSON property name to additionalInfo but I didn't want to change that). This is done in Angular as
export class ServerResponseAPI{
'additional-info':string;
constructor ( public result:string,
public additionalInformation:string){
this['additional-info'] = additionalInformation;
}
}
In my code, I now access the keys as
let jsonResponse:ServerResponseAPI = res.body //contains result and additional info
console.log("result: "+jsonResponse.result+", additional info:"+jsonResponse['additional-info'])
let jsonQuestionList:string = jsonResponse['additional-info']

Related

Associating xxxx_id with xxxx.id

I am running into a problem where when I submit a "property listing" I get this response:
{"owner_id":"Batman","address":"test","state":"test","sale_price":"test"}
The thing is "owner_id" is supposed to equal or associate with owner's id in a different table/JSON file (e.g owner_id = owner.id), not a string in this case which is why the object is not saving on the back-end.
Is anyone in vanilla JavaScript able to show me an example on how to associate owner_id and owner.id?
It'd be more like :
{
owner: {
id: "Batman"
},
address: "test",
state: "test",
sale_price: "test"
}
You should take a look at : https://www.w3schools.com/js/js_json_objects.asp
EDIT: Not sure how you're fetching this data but it seems like you want to handle the response you're getting.
Here is a simple GET request using the fetch api:
fetch('http://example.com/heroes') //this is the path to your source where you're getting your response data
.then((response) => {
return response.json();
//above you return a promise containing your response data
//you can also handle your response before declaring it in a var here
})
.then((myJson) => {
//you have stored your response data as a var myJson
console.log(myJson);
//here you can work your response data in any way you need
// to show an example (not that you would do this) I've provided a owner object that checks if it's property is equal to the incoming data
var owner = {
"id": Batman,
}
if ( myJson.owner_id === owner.id ) {
//do something here
}
});
More info here.

Access items inside of an array of objects

I have a rather simple JSON file that I'm trying to access the items inside of. I had this working but for some reason it no longer works and it is making my brain hurt. Here is the JSON:
[
{
"firstItem":
{
"message": "firstItem is working",
"value": ["hello", "world"]
}
},
{
"secondItem":
{
"message": "secondItem is working",
"value": ["hello", "aliens"]
}
}
]
Note that there is an array of two objects (firstItem and secondItem) which have objects within them (message and value). I am trying to access these items like so:
// the json from above is equal to json
json.map(items => {
console.log(items.firstItem.message)
console.log(items.firstItem.value.join(", "))
console.log(items.secondItem.message)
console.log(items.secondItem.value.join(", "))
})
As always, any help would be appreciated.
Edit: I put the closing parenthesis on the joins. This was not part of my issue. I guess I'm too used to VSCode doing it for me. :)
You were missing a closing parentheses on your console.log join statements. The second and larger problem was that with map you are looping through firstItem first and then secondItem, so in the first iteration map doesn't know what secondItem is. I changed the names of each object to "item" and halved the code inside map to solve the problem:
const json = [
{
"item":
{
"message": "firstItem is working",
"value": ["hello", "world"]
}
},
{
"item":
{
"message": "secondItem is working",
"value": ["hello", "aliens"]
}
}
]
json.map(items => {
console.log(items.item.message);
console.log(items.item.value.join(", "));
})
Note that there is an array of two objects (firstItem and secondItem) which have objects within them (message and value). I am trying to access these items like so:
The example you show, shows an array containing two objects, where the first object has a property called firstItem and the second property has a property called secondItem. The properties in both the objects are objects themselves and both have two properties called message and value.
I hope that makes sense.

Function getting firebase object returns hard to use object

What I am trying to do
I am creating a social media app with react native and firebase. I am trying to call a function, and have that function return a list of posts from off of my server.
Problem
Using the return method on a firebase query gives me a hard to use object array:
Array [
Object {
"-L2mDBZ6gqY6ANJD6rg1": Object {
//...
},
},
]
I don't like how there is an object inside of an object, and the whole thing is very hard to work with. I created a list inside my app and named it items, and when pushing all of the values to that, I got a much easier to work with object:
Array [
Object {
//...
"key": "-L2mDBZ6gqY6ANJD6rg1",
},
]
This object is also a lot nicer to use because the key is not the name of the object, but inside of it.
I would just return the array I made, but that returns as undefined.
My question
In a function, how can I return an array I created using a firebase query? (to get the objects of an array)
My Code
runQ(group){
var items = [];
//I am returning the entire firebase query...
return firebase.database().ref('posts/'+group).orderByKey().once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
//post contents
});
});
console.log(items)
//... but all I want to return is the items array. This returns undefined though.
})
}
Please let me know if I'm getting your question correctly. So, the posts table in database looks like this right now:
And you want to return these posts in this manner:
[
{
"key": "-L1ELDwqJqm17iBI4UZu",
"message": "post 1"
},
{
"key": "-L1ELOuuf9hOdydnI3HU",
"message": "post 2"
},
{
"key": "-L1ELqFi7X9lm6ssOd5d",
"message": "post 3"
},
{
"key": "-L1EMH-Co64-RAQ1-AvU",
"message": "post 4"
}
...
]
Is this correct? If so, here's what you're suppose to do:
var items = [];
firebase.database().ref('posts').orderByKey().once('value', (snapshot) => {
snapshot.forEach((child) => {
// 'key' might not be a part of the post, if you do want to
// include the key as well, then use this code instead
//
// const post = child.val();
// const key = child.key;
// items.push({ ...post, key });
//
// Otherwise, the following line is enough
items.push(child.val());
});
// Then, do something with the 'items' array here
})
.catch(() => { });
Off the topics here: I see that you're using firebase.database().... to fetch posts from the database, are you using cloud functions or you're fetching those posts in your App, using users' devices to do so? If it's the latter, you probably would rather use cloud functions and pagination to fetch posts, mainly because of 2 reasons:
There might be too many posts to fetch at one time
This causes security issues, because you're allowing every device to connect to your database (you'd have to come up with real good security rules to keep your database safe)

Serializing a JSON object for a Django URL

I have a JSON object that looks like this:
var obj = {
"selection":[
{
"author":"John Doe",
"articles":[
"Article One",
"Article Two"
]
}
]
}
I want to pass this object to Django to render a view that displays 'Article One' and 'Article Two' upon render. I first serialize the JSON object so that it can be appended to a URL; I use $.param(obj) for serialization. Now the JSON object looks something like this:
"selection%5B0%5D%5Bauthor%5D=John+Doe&selection%5B0%5D%5Barticles%5D%5B%5D=Article+One&selection%5B0%5D%5Barticles%5D%5B%5D=Article+Two"
Now I can append this to a path and use window.open(url) the view will handle everything else. On the Django end, I was surprised to see that the structure of the JSON object has changed to this:
"selection[0][author]=John+Doe&selection[0][articles][]=Article+One&selection[0][articles][]=Article+Two"
I want to be able to use the JSON object as a dict e.g.:
obj = request.GET.get('selection')
obj = json.loads(obj)
print(obj[0].author)
...
How should I handle this JSON structure on the Django side of things?
You are not properly serializing the object to JSON, even if you say you do. The correct way would be to use JSON.stringify(), as #dunder states.
Than you parse it back to an object with JSON.parse(strignifiedJson).
var obj = {
"selection":[
{
"author":"John Doe",
"articles":[
"Article One",
"Article Two"
]
}
]
}
// Stringify and encode
var objAsParam = encodeURIComponent(JSON.stringify(obj));
// Send as a param, for example like http://example.com?obj=YourStringifiedObject...
// Parse it back:
var parsedObj = JSON.parse(decodeURIComponent(objAsParam));

Can I output JSON where the ID is the key rather than it being an array in ASP.NET MVC (C#)

So in ASP.NET MVC I have a Controller action somewhat like this:
public JsonResult People()
{
var people = db.People.ToList();
return Json(people);
}
and when ajaxed this will return something like this:
[
{
"ID": 1,
"Name": "John Smith"
},
{
"ID": 2,
"Name": "Daryl Jackson"
}
]
However, what I'm looking for is not a JSON array of the records as shown above, but more a JSON object where the IDs of each record is the key and then the record nested as the value, like so:
{
1: {
"Name": "John Smith"
},
2: {
"Name": "Daryl Jackson"
}
}
My initial thought would be to create a Dictionary in C# similar to this structure and pass it into Json() however the method does not know how to handle Dictionary objects.
Is there a way to achieve this kind of structure in C#? Currently I'm having to resort to restructuring it on the client-side or using loops to find a record with the ID I'm searching for. It'd be nicer if I could just get the record by ID in Javascript. Am I going about this all wrong? I'm new to the ASP.NET MVC environment.
Any suggestions would be greatly appreciated. Thank you :)
You can use the ToDictionary() extension method.
public ActionResult People()
{
var peopleDictionary = db.People
.Select(x=> new { Id = x.Id, Name= x.FirstName})
.ToDictionary(d => d.Id.ToString(), p => p);
return Json(peopleDictionary, JsonRequestBehavior.AllowGet);
}
Assuming your People table has an Id and FirstName column, this code will return a json dictionary like this from your table data
{ "101" : {"Id":101,"Name":"John"},"102":{"Id":102,"Name":"Darryl"} }
Using the Json metod, You cannot serialize a dictionary where the dictionary key is of type int, so you need to explicitly convert your int value to a string.
If you want to get a specific user from the a userId, you can use the dictionary style syntax yourJsObject[key]
var url="PutRelativeUrlToReportScoreHere";
$.getJSON(url, function(data) {
console.log(data);
//Get the User with Key 102
console.log(data[102]);
});

Categories