Generating nodes using ruby and displaying them with javascript error - javascript

So Im trying to extract nodes from my database (by going through it recursively) and then displaying the json code i have to a javascript library. The problem is that the library is not identifying the json array output because it has extra quotation marks and a slash (/). Here is the code:
data = {
"nodes":
"\"User1:{'color':'green','shape':'dot','label':'You'},
User2:{'color':'green','shape':'dot','label':'You'},
User3:{'color':'green','shape':'dot','label':'You'}\""
,"edges":{}};
And I want it to look something like this:
var data = {
"nodes":{
"You":{'color':'green','shape':'dot','label':'You'},
Ben:{'color':'black','shape':'dot','label':'Ben'},
David:{'color':'black','shape':'dot','label':'David'}
},
"edges":{
You:{ Ben:{}, David:{} },
Ben:{ David:{}}
}
};
In my user_controller I am using this:
def make_json(node, string = "")
node[1].each do |n|
string += node[0] + "{'color':'green','shape':'dot','label':'You'},"
return make_json(n, string )
end
return string + node[0] + "{'color':'green','shape':'dot','label':'You'}"
end
And finally, this:
#data = {}
#data['nodes'] = make_json(#user_tree[0]).to_json
#data['edges'] = {}
I tried using the replace method, but the data variable doesnt seem to be a String so I can't just replace the quotation marks. I'd appreciate any sort of help.
Thanks!

The reason for the extra \" in the output is that you are calling to_json on the return value from your make_json method which is a string.
Its hard to see exactly what you are trying to do in make_json, but assuming that you want to use the output as a value in your #data hash and then convert that to json I think you would be better off having make_json build a hash and return that. Generally when returning a JSON response the easiest solution is to build a data structure out of Ruby hashes and arrays and then call to_json on that. Here is a much simplified example (I don't know what the #user_tree is so I don't understand the recursive step but I hope this gives you the general idea):
def make_json(node, hash = {})
node[1].each do |n|
hash[n[0]] = {:color => 'green', :shape => 'dot', :label => n[0]}
end
hash
end
If you try to construct the JSON string yourself it is easy to trip up. The output that you say you are aiming for is not valid JSON though it may be valid JavaScript. Strings need to be wrapped in double quotes, e.g.
"Ben": {"color": "black", "shape": "dot", "label": "Ben"}
rather than:
Ben:{'color':'black','shape':'dot','label':'Ben'}

Related

How do I parse part of a JSON object that has mixed string and numbers?

I have a JSON file that was processor generated with lines like this
jsonData: "{data: [350.23,250.32,150.34,340.50,236.70,370.45,380.55]}"
I can target the 'jsonData' object but that returns everything within the double quotes as a string.
I tried ...dataset[0].jsonData[8] which returns the '3' from the first value. I guess I could throw the mixed strings into a JS function and use regex to remove the extra stuff, but thats probably the hackyest way to do this.
Whats the easiest way to target the values only?
If you want to interact with it like the list I would consider something like
var list = jsonData.split("[")[1].split("]")[0].split(",")
Console.log(list);
The console reads:
[
'350.23', '250.32',
'150.34', '340.50',
'236.70', '370.45',
'380.55'
]
From here you can use list[3] to get 340.50
If you don't want to spend the time fixing your JSON just do this:
let values = "{data: [350.23,250.32,150.34,340.50,236.70,370.45,380.55]}".split(',').map(_ => _.replace(/[^0-9.]/g,''))
console.log(values)

How to parse an array from a JSON string?

I have the following C# method:
[HttpPost]
public JsonResult GetDateBasedRegex(string date)
{
string[] arr = CommonMethods.GetDateBasedRegex(date);
JsonResult retVal = Json(JsonConvert.SerializeObject(retVal));
return retVal;
}
arr contains the following:
And retVal.Data contains this value:
That C# method is invoked by this JS:
var date = $('#myDateField').val();
AjaxRequest(date, 'html', 'post', '/Common/GetDateBasedRegex', 'application/json;', function (response)
{
var result = JSON.parse(response);
}
);
I've set a breakpoint and added a watch for both response and result:
response is slightly longer because it escapes the quotes but otherwise they're the same value.
Both variables are a single string. How can I parse this value into an array? I looked at a variety of "suggested questions" by SO when typing this question,
the most relevant one seems to be this: Javascript how to parse JSON array but I'm already doing what the selected answer suggests.
I tried making a JS fiddle: http://jsfiddle.net/zc2o6v52/ but due to the quotes added by the debugger I had to tweak the values slightly in order to get it to work. If I use the variable csharpJsonSerializedString or result the loop works but when I use response I get an "Uncaught SyntaxError: Unexpected string" error in my console.
What am I doing wrong? How do you parse an array from a JSON string?
EDIT
C# retval's value:
"[\"^[0-9]{9}[A-Z0-9]{0,3}$\",\"^[A-Z]{1,3}([0-9]{6}|[0-9]{9})$\"]"
JS response's value:
""[\"^[0-9]{9}[A-Z0-9]{0,3}$\",\"^[A-Z]{1,3}([0-9]{6}|[0-9]{9})$\"]""
JS result's value:
"["^[0-9]{9}[A-Z0-9]{0,3}$","^[A-Z]{1,3}([0-9]{6}|[0-9]{9})$"]"
Grabbed all of these by right click -> Copy value, so they include the 'wrapping' set of quotes to make it a string.
The C# looks like it's formed right for how one would define a JS array. It seems like response is wrapped with an extra set of quotes though?
I also tried changing my JS to define var result = ['','']; outside of the ajax call, then to update its value with JSON.parse() but it still remains a single string afterwards.
Assuming this is the exact value your API returns on the POST request
"[\"^[0-9]{9}[A-Z0-9]{0,3}$\",\"^[A-Z]{1,3}([0-9]{6}|[0-9]{9‌​})$\"]"
This is no json, so JSON.parse can't work. Your JSON should look like this:
[
"^[0-9]{9}[A-Z0-9]{0,3}$",
"^[A-Z]{1,3}([0-9]{6}|[0-9]{9‌​})$"
]
The best way would be to fix the backend to return the right value (this might point you in the right direction). Otherwise, you need to get rid of the quotation marks at the beginning and end which are added to your result variable:
var result = "\"[\"^[0-9]{9}[A-Z0-9]{0,3}$\",\"^[A-Z]{1,3}([0-9]{6}|[0-9]{9‌​})$\"]\"";
result = result.substring(1, result.length-1);
var jsonData = JSON.parse(result);
for (var i = 0; i < jsonData.length; i++) {
console.log(jsonData[i]);
}
If that doesn't work, check how your response data in the ajax function differs from the valid json mentioned above.

Escaping JSON to avoid changing the insert string

I have the following json string that should be inserted directly into the database in a single column:
const jsString = JSON.stringify({"escaping":"d\"on't"});
const insertion = [{"a":2,"json":jsString}];
const query = pgp.helpers.insert(insertion,["a","json"],"tbl");
however what actually ends up in the database is:
{"escaping":"d"on't"}
removing the escaping \ in d"on't and making the string invalid json. Is there some way to avoid this?
This would be beneficial since it would be nice if my valid json would remain so.
Don't stringify your data into JSON, use it directly
Set column formatting as JSON, using :json modifier
const data = {escaping: "d\"on't"};
const insertion = [{a:2, json:data}];
const query = pgp.helpers.insert(insertion, ["a", "json:json"], "tbl");
But if your data is always an object, then you don't even need to use the :json modifier, it will be automatically formatted as correct JSON.
For more details see the flexibility of the ColumnSet type. You can manipulate your input data in every thinkable way.
This string in js const jsString = JSON.stringify({"escaping":"d\\\"on't"}); will result in this {"escaping":"d\\\"on't"}
While this string in js const jsString = JSON.stringify({"escaping":"don't"}); will result in this {"escaping":"don't"}

How to convert a string to JSON format?

I was getting list in array form. So at first place i converted array list to string-
var myJsonString = JSON.stringify(result);
myJsonString="[{"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
},
{"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
}]"
But again i need to convert myJsonString to Json format, What i need to do? I mean i need to replace 1st" and last ", I guess
You need to call parse now.
JSON.parse(myJsonString)
First, if you ever find yourself building a JSON string by concatenating strings, know that this is probably the wrong approach.
I don't really understand how the first line of your code relates to the second, in that you are not doing anything with JSON-encoded string output from result, but instead just overwriting this on the following line.
So, I am going to limit my answer to show how you could better form JSON from an object/array definition like you have. That might look like this:
// build data structure first
// in this example we are using javascript array and object literal notation.
var objArray = [
{
"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
},{
"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
}
];
// now that your data structure is built, encoded it to JSON
var JsonString = JSON.stringify(objArray);
Now if you want to work with JSON-encoded data, You just do the opposite:
var newObjArray = JSON.parse(JsonString);
These are really the only two commands you should ever use in javascript when encoding/decoding JSON. You should not try to manually build or modify JSON strings, unless you have a very specific reason to do so.

Passing an array from javascript to ruby with sinatra

What I want to accomplish is to pass a 2D array from javascript to something that ruby will recognize. All objects are strings
I have been using gon-sinatra, but it doesn't do exactly what I need.
I can pass store the string I want to pass as gon.text doing
#temp = gon.text
array.push(#temp)
This doesn't work because it shows gon.text as a nil object type, when I want it as a string. gon.text.to_s returns an empty string, so when I try to display it, nothing happens. alert("<%= #temp %>") // displays an empty string
I'm at a bit of a loss here and don't know the best way to approach this. Would it be better to store the array as a json, and then read in the json using ruby instead?
Yes. Convert your array to json(a string) with js:
var data = JSON.stringify(yourArray);
Send the string to your ruby script. Then parse the string into an Array with ruby:
require 'json'
arr = JSON.parse(the_string)
In Javascript you do something like the following:
var myArray = [ ['str1','str2'], ['str3','str4'] ];
$.get('/endpoint', { myArray: myArray })
And your endpoint with sinatra would be:
get 'endpoint' do
myArrayStr = params[:myArray]
error!('invalid array') unless myArrayStr
#myArray = JSON.parse(myArrayStr)
gon.rabl 'goners/yourFile.rabl', :instance => self
end
And in your gon file you would reference this with:
alert(gon.myArray[0][0]); // str1

Categories

Resources