Why does my JSON parse with some missing key value pairs? - javascript

I have a Rails backend that would serve JSONs like this: (This e.g. is 2.json)
{"id":2,"name":"Magic","location":"Cyberjaya","surprise_type":"Great","instructions":"test","status":"awesome","pricing_level":3,"longitude":"2.90873","latitude":"101.655027","created_at":"2016-02-02T07:19:18.247Z","updated_at":"2016-02-02T12:59:14.403Z"}
and an AngularJS app.js code that goes like this (the relevant parts only):
.factory('MarkersLoc', function($resource) {
debugger;
return $resource("http://localhost:3000/surprises/:id.json");
})
.factory('Markers', function(MarkersLoc) {
var markers = [];
return {
getMarkers: function(){
return MarkersLoc.query().$promise.then(function(response){
debugger;
markers = response;
console.log("Markers: ", markers);
return markers;
});
}
}
})
The problem that I'm having is that, even at the point of the debugger, response is an array of objects that have all the attributes from the JSON except longitude, latitude, created_at and updated_at.
Unfortunately I am unable to determine the reason why these four key-value pairs are omitted when it's being read and returned. Is there something that should be controlling which key-value pair is being processed that I have left out on? Wouldn't the entire JSON be parsed and converted into the object?

The missing values are the result of the data being serialized by the controller on the backend. To view all the keys, ensure all the attributes are defined in the serializer:
class SurpriseSerializer < ActiveModel::Serializer
attributes :id,
:name,
:location,
:surprise_type,
:instructions,
:status,
:pricing_level,
# Add the missing attributes to the serializer
:longitude,
:latitude,
:created_at,
:updated_at
end

Related

Having Issues with handling Python dictionaries in Javascript flask templates

So I am building a web application using flask that can track mutiple vehicles and provide updates. The python script helps gather all the data and puts them in a dictionary.
I am sending this dictionary over to the index.html with the javascript code within the HTML that initializes a map and places markers based on the coordinates received from python.
The issue I am having is this dictionary is not being parsed properly in js and as a result I get no data.
Right now I have the {{truck_dict}} placeholder to hold the dict object from python in the html.
PS. I am not the best at JS so dont judge XD
#Python Code
return render_template('pages/index.html', trucks = truck.driver_locator(truck.locations()))
#Even when I jsonify/json.dump the variable in the trucks object, nothing happens
#JS Code
var truck_dict = {{trucks | tojson}}
var i;
for (var key in truck_dict){
var value = truck_dict[key];
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: value
},
properties: {
title: 'Mapbox',
description: '1303'
}
}]
};
SAMPLE OUTPUT of the python generated dict
{'1301': [43.1220307, -78.9352247], '1302': [42.3107737, -77.2519131], '1304': [40.3809016, -74.5665863], '1305': [40.2453049, -74.5707928], '1303': [39.6435448, -75.9325289]}
Here is the output:
var truck_dict = {'1301': [43.1220307, -78.9352247], '1302': [42.3107737, -77.2519131], '1304': [40.3809016, -74.5665863], '1305': [40.2453049, -74.5707928], '1303': [39.6435448, -75.9325289]};
for (var i in truck_dict) {
console.log(i, truck_dict[i]);
}
output:
1301 [43.1220307, -78.9352247]
1302 [42.3107737, -77.2519131]
1303 [39.6435448, -75.9325289]
1304 [40.3809016, -74.5665863]
1305 [40.2453049, -74.5707928]
So, you need to log truck_dict, like:
var truck_dict = {{trucks | tojson}};
console.log(trucks);
console.log(truck_dict);
You're trying to index a dictionary.Using truck_dict[I] doesn't work here because your indices are not numbers (not possible in js anyway).
You need to access dictionary elements with their keys (ex. truck_dict['1301'] or truck_dict.1301) NOT indexes. If you want to iterate over each key (which you can use to reference the value mapped to that key), use:
for(var key in truck_dict) {
var value = truck_dict[key];
// do what you need with value and key here
}

why does returning JsonResult from a Dictionary change the sort order?

I have the following controller action:
public JsonResult GetInvestors(int bank)
{
var investors = _context.Investors
.Where(i => i.BankNumber == bank)
.Select(i => new { InvestorId = i.InvestorId.ToString(), InvestorName = i.InvestorName + " (" + i.BankNumber + ")" })
.OrderBy(i => i.InvestorName)
.ToDictionary(i => i.InvestorId, i => i.InvestorName);
return Json(investors, JsonRequestBehavior.AllowGet);
}
And the following javascript to call that action that for now just starts the debugger so I can browse the result:
function getInvestors(bank)
{
$.ajax
({
url: "/InvestorDetail/GetInvestors",
type: "POST",
data: { bank: bank },
dataType: "json",
success: function (returnedData) { debugger; }
});
}
If I watch investors in the controller action, it is sorted by the investor name, which is what I want. However, when I get to the javascript debugger and watch returnedData, the data comes in sorted by the investor ID.
Alternately, if I put OrderBy after ToDictionary and order by Value, in the javascript debugger the json structure of the result is different but it is sorted by investor name like I want.
Why would the sort order change when returned from a Dictionary?
Thank you.
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.
See official msdn documentation
You can use sorted Dictionaries though, or sort it properly on the client side.
You can't sort a dictionary, although you can get a representation of a sorted dictionary!
You could try something like
import collections
Dictionary_Sorted = collections.OrderedDict(x)
x being an object with key valued pairs.
This is the same case for C# as well.
I like to change my Dictionary to a list by say.
var newList = thisDictionary.ToList();
newList.Sort((a,b) => a.Value.CompareTo(b.Value));
I like the one liner approach. It is simple and elegant.
If you would like to sort it descending then switch the values as such.
newList.Sort((a,b) => b.Value.CompareTo(a.Value));

Correct proceedure for JSON/Javascript parsing in Rails?

In Rails, I am querying the database to build a data object for highcharts.
Here is my method from my controller:
def build_data_for_chart
data_array = Array.new
#data_array_as_json = ''
#issues.each {
|issue|
# returns an array of KeyIssue objects for a given issue
given_issue_array = KeyIssues.where(issue: issue).all
a = Array.new
#loop through each element extracting the timedate and % and add to new array
given_issue_array.each {
|entry|
a.push([entry.datetime.utc.to_date, entry.percentage])
}
#build the hash for an individual issue
temp_hash = {:name => issue, :data => a, :animation => false}
#add the individual issue and all its data to a final array that contains all the issues.
data_array.push(temp_hash)
}
#data_array_as_json = data_array.to_json.html_safe
end
Now I am trying to pull it out in a script in my view.
--- script ---
var data = $.parseJSON(<%= #data_array_as_json %>);
--- script ---
When I print to console, I can see the objects and all their data. Also when I print to html the output looks correct:
"[{\"name\":\"ABORIGINAL & NATIVE TITLE ISSUES\",\"data\":[[\"1993-11-01\",32],[\"1994-06-01\",27],[\"1994-09-01\",33],[\"1995-06-01\",26],[\"1995-09-01\",24],[\"1996-01-01\",20],[\"1996-09-01\",27],[\"1997-01-01\",33],[\"1997-06-01\",36],[\"1997-09-01\",36],[\"1998-01-01\",37],[\"1998-05-01\",33],[\"1998-09-01\",31],[\"1999-05-01\",30],[\"1999-09-01\",28],[\"2000-01-01\",30],[\"2000-05-01\",31],[\"2000-09-01\",34],[\"2001-01-01\",32],[\"2001-06-01\",29],[\"2001-09-01\",28],[\"2002-02-01\",25],[\"2002-06-01\",27],[\"2002-10-01\",25],[\"2003-02-01\",24],[\"2003-06-01\",26],[\"2003-10-01\",27],[\"2004-02-01\",27],[\"2004-06-01\",26],[\"2005-06-01\",30],[\"2006-06-01\",27],[\"2007-06-01\",31],[\"2008-07-01\",29]],\"animation\":false}]"
But when I go to print the data variable it is null (obviously due to not being valid input). What am I messing up?
FYI..
I needed to wrap it in single quotes.. to make it work..
$.parseJSON(' <%= #data_array_as_json %> ');
You can try this:
<script type="text/javascript">
var data = <%== data_array.to_json %>
</script>

Grails hashmap variable in javascript gives different format

In my grails controller:
assert result == [hus:['hus#gmail.com', 'SE', 'on', '9908899876'], vin:['vin#gmail.com', 'SD', 'on', '7765666543']]
println "result is::"+result
println result.getClass()
[result:result] //passing model to view
which prints :
[hus:[hus#gmail.com, SE, on, 9908899876], vin:[vin#gmail.com, SD, on, 7765666543]]
class java.util.LinkedHashMap
but when i get this hashmap from my view page and access from javascript
$(function(){
alert('${result}');
});
it prints
{
hus=[hus#gmail.com,SE,9902766542],
vin = [vin#gmail.com, SE,887654433]
}
which is not valid object , is not a valid object, (: replaced by =) it should be
{ hus:[hus#gmail.com,SE,9902766542], vin : [vin#gmail.com, SE,887654433] }
why it is so? how do i correct it?
Your current output is produced by toString() of the Map result which can be used to
print the data but is not very useful to transfer it to javascript.
You should convert the result to json in your controller:
def json = result as JSON
and return it to your model:
[json : json ]
After that you can create an object in Javascript using JQery.parseJSON:
var obj = jQuery.parseJSON("${ json.toString() }");

How to append database values to JSON data

I have a JSON which lists the values from database. Below is the JSON data of 2 rows from the database.
[{"Name":"P1","Description":"pd1","Value":"v1","Attribute":"a1"},{"Name":"P1","Description":"pd1","Value":"v2","Attribute":"a2"}]
database values are the result of a left join query. Only 'Value' and 'Attribute' fields are different. Can I append that fields to JSON instead of multiple sets of record? I know there is 'push' to do this, but I am unaware where and how to use this in my code. below is the code for fetching values from db and serializing the values.
GetProfileDataService GetProfileDataService = new BokingEngine.MasterDataService.GetProfileDataService();
IEnumerable<ProfileData> ProfileDetails = GetProfileDataService.GetList(new ProfileSearchCriteria { Name = strProfileName });
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string strSerProfileDetails = javaScriptSerializer.Serialize(ProfileDetails);
context.Response.ContentType = "text/json";
context.Response.Write(strSerProfileDetails);
Below is my getJSON
$(document).ready(function () {
$.getJSON('ProfileHandler.ashx', { 'ProfileName': 'Profile 1' }, function (data) {
$.each(data, function (k, v) {
alert(v.Attribute+' : '+v.Value);
});
});
});
Please help me here.
There are several things you can do.
Store value and attribute as arrays:
[{"Name":"P1","Description":"pd1","Value":["v1", "v2"],"Attribute":["a1", "a2"]}]
Or store them as a 'symbol'-separated string:
[{"Name":"P1","Description":"pd1","Value":"v1;v2"],"Attribute":"a1;a2"]}]
In order to use the first case, you'll have to try and figure out how to format the ProfileDetails in order to have javaScriptSerializer.Serialize parse it correctly. You will likely have to convert your data first in order for this to work (i.e. convert value and attribute to arrays).
For the second case to work you could modify your GetProfileDataService.GetList method so that values and attributes are merged to symbol-separated strings (something like this: GROUP BY to combine/concat a column)

Categories