Cast JSON to Mongoose Schema to call Schema Method - json

I've looked at this question (Is there a native feature to convert string based JSON into Mongoose Schema object instance?) and it's related to my question but doesn't do exactly what I'm looking for.
Essentially, I have JSON I've fetched from an Express response and I'd like to cast it to a Mongoose object for the purposes of calling a schema method on the object.
My schema looks something like this:
var BlahSchema = new Schema({
folder: String,
filename: String,
original: String
});
...
// This is the function I wish to cal
BlahSchema.virtual('url').get(function () {
...
});
From what I understand, when I have an object matching BlahSchema, I can call the method via a simple object.url.
I have two questions. First, the JSON I'm retrieving these objects from erases their schema, right? I'm retrieving these from the database via Blah.search(...function(err, blahs)). This all gets encoded into a JSON object which I return via callback(req, res, search_result) where search_result is an object created via search_result.blahs = blahs, etc. Is there any way to preserve this schema across calls? This would be the preferred method.
Second, if the above is not possible, how do I re-cast JSON to schema without using the save() function mentioned in the answer to the question I pose above? I don't want to re-add objects to the database; I just want to use a method defined for that schema.
EDIT: Express is pretty sick. All you have to do is blah(object).method_name, where blah = mongoose.model('blah')

I save a User (Schema) object to redis in plain JSON.
Get the userData (string) and parse it to JSON object:
var user = new User(JSON.parse(userData))
... and you have all the methods of your User schema.

Related

Is there a way to define a to_json handler in GDScript?

I'm new to GDScript and am looking at how best to save data to a text file. to_json works well for basic types but I just get a reference id for any custom classes. I'd ideally like to pass a dictionary of data including some custom class elements to to_json and let it convert it all at once.
Like other languages provide a toString method for printing an object, is there anything that would let me specify how a class instance should be converted to JSON?
Yeah, you would just add something like the following to your class:
func to_json():
var data = {} #must create it as a dictionary or array
data["health"] = 5
#code to create json
var json
json = data.to_json() #dictionaries automatically have this function
return json
I think it really is that simple :)
Please note: I have not tested this code.

trying to convert data from Domino Access Service to a JSON string via JSON.stringify

I want to store the result from a call to a Domino Access Service (DAS) in a localStorage however when I try to convert the result object to a JSON string I get an error.
With DAS you get the result as an Array e.g.:
[
{
"#entryid":"1-CD90722966A36D758025725800726168",
"#noteid":"16B46",
Does anyone know how I get rid of the square brackets or convert the Array quickly to a JSON object?
Here is a snippet of my code:
var REST = "./myREST.xsp/notesView";
$.getJSON(REST,function(data){
if(localStorage){
localStorage.setItem('myCatalog',JSON.stringify(data));
}
});
Brackets are part of the JSON syntax. They indicate that this is an array of objects. And as you point to a view it is very likely that you would get more than one object back (one for each entry in the view).
So if you are only interested in the first element you could do this:
var REST = "./myREST.xsp/notesView";
$.getJSON(REST,function(data){
if(localStorage){
var firstRecord = data[0] || {};
localStorage.setItem('myCatalog',JSON.stringify(firstRecord));
}
});
Otherwise, you would need to define a loop to handle each of the objects :-)
/John

Manually parse json data according to kendo model

Any built-in ready-to-use solution in Kendo UI to parse JSON data according to schema.model?
Maybe something like kendo.parseData(json, model), which will return array of objects?
I was searching for something like that and couldn't find anything built-in. However, using Model.set apparently uses each field's parse logic, so I ended up writing this function which works pretty good:
function parse(model, json) {
// I initialize the model with the json data as a quick fix since
// setting the id field doesn't seem to work.
var parsed = new model(json);
var fields = Object.keys(model.fields);
for (var i=0; i<fields.length; i++) {
parsed.set(fields[i], json[fields[i]]);
}
return parsed;
}
Where model is the kendo.data.Model definition (or simply datasource.schema.model), and json is the raw object. Using or modifying it to accept and return arrays shouldn't be too hard, but for my use case I only needed a single object to be parsed at a time.
I actually saw your post the day you posted it but did not have the answer. I just needed to solve this problem myself as part of a refactoring. My solution is for DataSources, not for models directly.
kendo.data.DataSource.prototype.parse = function (data) {
return this.reader.data(data);
// Note that the original data will be modified. If that is not what you want, change to the following commented line
// return this.reader.data($.extend({}, data));
}
// ...
someGrid.dataSource.parse(myData);
If you want to do it directly with a model, you will need to look at the DataReader class in kendo.data.js and use a similar logic. Unfortunately, the DataReader takes a schema instead of a model and the part dealing with the model is not extracted in it's own method.

Standardized way to serialize JSON to query string?

I'm trying to build a restful API and I'm struggling on how to serialize JSON data to a HTTP query string.
There are a number of mandatory and optional arguments that need to be passed in the request, e.g (represented as a JSON object below):
{
"-columns" : [
"name",
"column"
],
"-where" : {
"-or" : {
"customer_id" : 1,
"services" : "schedule"
}
},
"-limit" : 5,
"return" : "table"
}
I need to support a various number of different clients so I'm looking for a standardized way to convert this json object to a query string. Is there one, and how does it look?
Another alternative is to allow users to just pass along the json object in a message body, but I read that I should avoid it (HTTP GET with request body).
Any thoughts?
Edit for clarification:
Listing how some different languages encodes the given json object above:
jQuery using $.param: -columns[]=name&-columns[]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
PHP using http_build_query: -columns[0]=name&-columns[1]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
Perl using URI::query_form: -columns=name&-columns=column&-where=HASH(0x59d6eb8)&-limit=5&return=column
Perl using complex_to_query: -columns:0=name&-columns:1=column&-limit=5&-where.-or.customer_id=1&-where.-or.services=schedule&return=column
jQuery and PHP is very similar. Perl using complex_to_query is also pretty similar to them. But none look exactly the same.
URL-encode (https://en.wikipedia.org/wiki/Percent-encoding) your JSON text and put it into a single query string parameter. for example, if you want to pass {"val": 1}:
mysite.com/path?json=%7B%22val%22%3A%201%7D
Note that if your JSON gets too long then you will run into a URL length limitation problem. In which case I would use POST with a body (yes, I know, sending a POST when you want to fetch something is not "pure" and does not fit well into the REST paradigm, but neither is your domain specific JSON-based query language).
There is no single standard for JSON to query string serialization, so I made a comparison of some JSON serializers and the results are as follows:
JSON: {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"logankeller#artiq.com","phone":"+1 (952) 533-2258","friends":[{"id":0,"name":"Colon Salazar"},{"id":1,"name":"French Mcneil"},{"id":2,"name":"Carol Martin"}],"favoriteFruit":"banana"}
Rison: (_id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller#artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258')
O-Rison: _id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller#artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258'
JSURL: ~(_id~'5973782bdb9a930533b05cb2~isActive~true~balance~'!1*2c446.35~age~32~name~'Logan*20Keller~email~'logankeller*40artiq.com~phone~'*2b1*20*28952*29*20533-2258~friends~(~(id~0~name~'Colon*20Salazar)~(id~1~name~'French*20Mcneil)~(id~2~name~'Carol*20Martin))~favoriteFruit~'banana)
QS: _id=5973782bdb9a930533b05cb2&isActive=true&balance=$1,446.35&age=32&name=Logan Keller&email=logankeller#artiq.com&phone=+1 (952) 533-2258&friends[0][id]=0&friends[0][name]=Colon Salazar&friends[1][id]=1&friends[1][name]=French Mcneil&friends[2][id]=2&friends[2][name]=Carol Martin&favoriteFruit=banana
URLON: $_id=5973782bdb9a930533b05cb2&isActive:true&balance=$1,446.35&age:32&name=Logan%20Keller&email=logankeller#artiq.com&phone=+1%20(952)%20533-2258&friends#$id:0&name=Colon%20Salazar;&$id:1&name=French%20Mcneil;&$id:2&name=Carol%20Martin;;&favoriteFruit=banana
QS-JSON: isActive=true&balance=%241%2C446.35&age=32&name=Logan+Keller&email=logankeller%40artiq.com&phone=%2B1+(952)+533-2258&friends(0).id=0&friends(0).name=Colon+Salazar&friends(1).id=1&friends(1).name=French+Mcneil&friends(2).id=2&friends(2).name=Carol+Martin&favoriteFruit=banana
The shortest among them is URL Object Notation.
How about you try this sending them as follows:
http://example.com/api/wtf?
[-columns][]=name&
[-columns][]=column&
[-where][-or][customer_id]=1&
[-where][-or][services]=schedule&
[-limit]=5&
[return]=table&
I tried with a REST Client
And on the server side (Ruby with Sinatra) I checked the params, it gives me exactly what you want. :-)
Another option might be node-querystring. It also uses a similar scheme to the ones you've so far listed.
It's available in both npm and bower, which is why I have been using it.
Works well for nested objects.
Passing complex objects as query parameters of a url.
In the example below, obj is the JSON object to pass into query parameters.
Injecting JSON object as query parameters:
value = JSON.stringify(obj);
URLSearchParams to convert a string to an object representing search params. toString to retain string type for appending to url:
queryParams = new URLSearchParams(value).toString();
Pass the query parameters using template literals:
url = `https://some-url.com?key=${queryParams}`;
Now url will contain the JSON object as query parameters under key (user-defined name)
Extracing JSON from url:
This is assuming you have access to the url (either as string or URL object)
url_obj = new URL(url); (only if url is NOT a URL object, otherwise ignore this step)
Extract all query parameters in the url:
queryParams = new URLSearchParams(url_obj.search);
Use the key to extract the specific value:
obj = JSON.parse(queryParams.get('key').slice(0, -1));
slice() is used to extract a tailing = in the query params which is not required.
Here obj will be the same object passed in the query params.
I recommend to try these steps in the web console to understand better.
You can test with JSON examples here: https://json.org/example.html

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;
}
});