I have an object defined like this:
function Question_Value__c () {
this.Id=null;
this.Name=null;
this.Question__c=null;
this.Order__c=null;
}
I'm trying to deserialize this JSON into several of these objects but I can't get it to work:
[{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"}]
Here's what I have so far:
allValues = new Array(new Question_Value__c());
$(returnedJSON).each(function() {
allValues.push($(this));
console.log(allValues[0].id);
});
Any assistance is much appreciated, I'm pretty new to working with JSON and javascript.
First of all, you need to put actual " in your JSON string, it is not valid to encode these caracters using ", that would be in HTML however.
In addition, if you want to populate your Question_Value_c objects with data, you should change your constructor function to something like:
function Question_Value__c(data) {
$.extend(this, data); //have a look at $.extend
}
Then you could do that (note that your objects do not have Question__c and Order__c properties):
var json = '[{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"},{"id":"a0Dd000000RTVsAEAX","name":"ee"}]',
allValues = [];
$.each($.parseJSON(json), (function () {
allValues.push(new Question_Value__c(this));
}));
console.log(allValues);
Related
We have an Angular 5 project in which we have a .json file which we're loading in a .ts file using XMLHttpRequest.
The .json file have the following content:
{
stringKey: "stringValue",
functionKey: function() {
console.log('function called!')
}
}
It throws the error: [json] value expected
If I open Chrome Devtool and set the above object as value - it works fine but not in the project
var obj = {
stringKey: "stringValue",
functionKey: function() {
console.log('function called!')
}
}
obj.functionKey();
Edit:
Is there a work around for storing functions in pure JSON?
You can't put a function inside a json file because it is a data format language,
but you can do it in a js file with a JS Object like you did:
var obj = {
functionKey: function() {
console.log('function called!')
}
}
obj.functionKey();
There is no function data type in JSON.
See the documentation. JSON supports objects, arrays, strings, numbers, booleans and null.
It is a data format, not a programming language. It doesn't make much sense for it to support functions.
See if that helps (functionKey needs to be a string, you would then use eval to get result)
var obj = {
stringKey : "stringValue",
functionKey: "(function() { console.log('function called')})()"
}
var result = eval(obj.functionKey);
https://jsfiddle.net/spdr80c7/
var obj = {
stringKey: "stringValue",
functionKey: function() {
console.log('function called!')
}
}
obj.functionKey();
Here you are just creating an Object obj not JSON.
Just try to convert this Object to JSON using JSON.stringify(obj) it will remove the functionKey as its not a string.
I am trying to develop an offline HTML5 application that should work in most modern browsers (Chrome, Firefox, IE 9+, Safari, Opera). Since IndexedDB isn't supported by Safari (yet), and WebSQL is deprecated, I decided on using localStorage to store user-generated JavaScript objects and JSON.stringify()/JSON.parse() to put in or pull out the objects. However, I found out that JSON.stringify() does not handle methods. Here is an example object with a simple method:
var myObject = {};
myObject.foo = 'bar';
myObject.someFunction = function () {/*code in this function*/}
If I stringify this object (and later put it into localStorage), all that will be retained is myObject.foo, not myObject.someFunction().
//put object into localStorage
localStorage.setItem('myObject',JSON.stringify(myObject));
//pull it out of localStorage and set it to myObject
myObject = localStorage.getItem('myObject');
//undefined!
myObject.someFunction
I'm sure many of you probably already know of this limitation/feature/whatever you want to call it. The workaround that I've come up with is to create an object with the methods(myObject = new objectConstructor()), pull out the object properties from localStorage, and assign them to the new object I created. I feel that this is a roundabout approach, but I'm new to the JavaScript world, so this is how I solved it. So here is my grand question: I'd like the whole object (properties + methods) to be included in localStorage. How do I do this? If you can perhaps show me a better algorithm, or maybe another JSON method I don't know about, I'd greatly appreciate it.
Functions in javascript are more than just their code. They also have scope. Code can be stringified, but scope cannot.
JSON.stringify() will encode values that JSON supports. Objects with values that can be objects, arrays, strings, numbers and booleans. Anything else will be ignored or throw errors. Functions are not a supported entity in JSON. JSON handles pure data only, functions are not data, but behavior with more complex semantics.
That said you can change how JSON.stringify() works. The second argument is a replacer function. So you could force the behavior you want by forcing the strinigification of functions:
var obj = {
foo: function() {
return "I'm a function!";
}
};
var json = JSON.stringify(obj, function(key, value) {
if (typeof value === 'function') {
return value.toString();
} else {
return value;
}
});
console.log(json);
// {"foo":"function () { return \"I'm a function!\" }"}
But when you read that back in you would have to eval the function string and set the result back to the object, because JSON does not support functions.
All in all encoding functions in JSON can get pretty hairy. Are you sure you want to do this? There is probably a better way...
Perhaps you could instead save raw data, and pass that to a constructor from your JS loaded on the page. localStorage would only hold the data, but your code loaded onto the page would provide the methods to operate on that data.
// contrived example...
var MyClass = function(data) {
this.firstName = data.firstName;
this.lastName = data.lastName;
}
MyClass.prototype.getName() {
return this.firstName + ' ' + this.lastName;
}
localStorage.peopleData = [{
firstName: 'Bob',
lastName: 'McDudeFace'
}];
var peopleData = localStorage.peopleData;
var bob = new MyClass(peopleData[0]);
bob.getName() // 'Bob McDudeFace'
We don't need to save the getName() method to localStorage. We just need to feed that data into a constructor that will provide that method.
If you want to stringify your objects, but they have functions, you can use JSON.stringify() with the second parameter replacer. To prevent cyclic dependencies on objects you can use a var cache = [].
In our project we use lodash. We use the following function to generate logs. Can be used it to save objects to localStorage.
var stringifyObj = function(obj) {
var cache = []
return JSON.stringify(obj, function(key, value) {
if (
_.isString(value) ||
_.isNumber(value) ||
_.isBoolean(value)
) {
return value
} else if (_.isError(value)) {
return value.stack || ''
} else if (_.isPlainObject(value) || _.isArray(value)) {
if (cache.indexOf(value) !== -1) {
return
} else {
// cache each item
cache.push(value)
return value
}
}
})
}
// create a circular object
var circularObject = {}
circularObject.circularObject = circularObject
// stringify an object
$('body').text(
stringifyObj(
{
myBooblean: true,
myString: 'foo',
myNumber: 1,
myArray: [1, 2, 3],
myObject: {},
myCircularObject: circularObject,
myFunction: function () {}
}
)
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Does not fix functions as requested, but a way to store variables locally...
<html>
<head>
<title>Blank</title>
<script>
if(localStorage.g===undefined) localStorage.g={};
var g=JSON.parse(localStorage.g);
</script>
</head>
<body>
<input type=button onClick="localStorage.g=JSON.stringify(g, null, ' ')" value="Save">
<input type=button onClick="g=JSON.parse(localStorage.g)" value="Load">
</body>
</html>
Keep all variables in object g. Example:
g.arr=[1,2,3];
note some types, such as Date, you'll need to do something like:
g.date=new Date(g.date);
stores locally per page: different pages have different gs
I have an JSON array that I read in, now I want to make each object in the array a KO observable so that it can be mapped to the function
function Person(data)
{
this.name = ko.observable(data.name);
this.age = ko.observable(data.age);
this.link = ko.observable(data.link);
}
function ViewModel()
{
var self = this;
self.Persons = ko.observableArray([]);
var JSONdataFromServer;
$.getJSON('http://127.0.0.1:8080', function(data) {
self.Persons(data);
for(var k in self.Persons) {
k = $.map(k, function(item) { return new Person(item) });
}
});
}
However When I run this code(this is only a portion of it) I get the error "Cannot use 'in' operator to search for '0' in G". Again all I want to do is convert the JSON object in the Persons array to a Person KO observable object.
self.Persons is an observableArray, so if you want to look at its contents, you need to invoke it:
for (var k in self.Persons())
Other things you're doing are perplexing me. To convert the JSON object to an observableArray of Persons, you'd likely do something like this (depending on what the data looks like -- you don't say):
$.getJSON('http://127.0.0.1:8080', function(data) {
var arrayOfPersons = ko.utils.arrayMap(data, function (item) {
return new Person(item);
});
self.Persons(arrayOfPersons);
});
Avoid manually mapping incoming data from the server. Use ko mapping plugin for this. Maintaining your client side viewModel in sync with data from the server is very hard as soon as your viewModel starts growing, better to leverage this to ko mapping, which is also very flexible if you need more control over how the mapping should work.
I am fairly new to Grails MVC and javascript.
I am encountering a problem wherein i want to pass a map object from the controller to a javascript function.
Currently two parameters are passed to the javascript function which are comma seperated and this works fine
eg. someControllerFunction() {
variableLink = "j-javaScriptFunction-${stringArgs1},${stringArgs2}" // This is a link for an ajax call
}
The javascript function structure looks like this
function someJavaScriptFunction (details) {
var d = details.split(",");
var strintArgs1 = d[0];
var stringArgs2 = d[1];
ajax":{
"url":"${request.contextPath}/controller/methodInController?strintArgs1=" + strintArgs1 + "&stringArgs2=" +stringArgs2
},
}
The Controller function which is called in the ajax currently looks like this
methodInController (String strintArgs1,String strintArgs2){
//some operation
}
Now i want to pass a map object from the controller function to the javascript function but i am not able to as the javascript considers the map as an invalid String object.
Below are the changes i have made to the three functions but i am getting an error during the ajax call saying "Uncaught SyntaxError: Unexpected string"
eg. someControllerFunction() {
variableLink = "j-javaScriptFunction-${stringArgs1},${stringArgs2},${mapArg}" // This is a link for an ajax call
}
The map object looks like this
mapArg = [a:[],b:[],c:[],d:[]]
The javascript function structure looks like this
function someJavaScriptFunction (details) {
var d = details.split(",");
var strintArgs1 = d[0];
var stringArgs2 = d[1];
var mapArg = d[2];
ajax":{
"url":"${request.contextPath}/controller/methodInController?strintArgs1=" + strintArgs1 + "&stringArgs2=" +stringArgs2 + "&mapArg=" +mapArg
},
}
The Controller function which is called in the ajax currently looks like this
methodInController (String strintArgs1, String strintArgs2, Object mapArg){
//some operation
}
It might be something to do with the way i am passing it to the javascript function but i am not able to figure out the exact reason.
Could anyone please help me to understand what am i doing wrong.
Thanks in advance
It looks like you might have to cast the map to JSON first (which would explain why its a string). See this answer: https://stackoverflow.com/a/2064341/1902587
I'm attempting to create a function lookup in Javascript essentially mapping a data type to a function that does something for that data type. Right now I have something similar to:
var Namespace = Namespace || {};
Namespace.MyObj = function () {
var stringFunc = function(someData) {
//Do some string stuff with someData
};
var intFunc = function(someData) {
//Do some int stuff with someData
};
var myLookUp = {
'string': stringFunc,
'int' : intFunc
};
return {
PublicMethod: function (dataType, someData) {
myLookUp[dataType](someData);
}
};
} ();
When I invoke Namespace.MyObj.PublicMethod(dataType, someData) I get an error that myLookUp is not defined. I'm assuming I'm not going about setting up the function lookup object correctly, but not sure how to do so. Thanks for any help.
The problem might simply be incorrect case
myLookup[dataType](someData);
should be (notice the capital U)
myLookUp[dataType](someData);
Just looked at my post after I wrote it up, stupid oversight, I'm declaring the properties as strings, instead of just properties.
....
var myLookUp = {
string: stringFunc,
int: intFunc
};
....
Fixes the issue.
Some additional follow up, in my actual code dataType is the result of a jQuery select. Don't know why or if this would be browser dependant (I'm using FireFox), but using double quotes around the property definition works, single quotes does not, and no quotes works as well. :-\