Assume I have the following JSON structure.
data = {
questions: [
{color:
{name: 'What is your fav color?',
type: 'input'
}
},
{...more question like this...}
],
layouts: [
{row_1:
{format: '...', $ref: '#/questions/color', id: 1}
},
{...more format like this...}
]
}
Using Javascript, is it possible to "expand" the $ref from '#/questions/color' to the actual object defined in this JSON? Or do I have to write a custom function to traverse through the JSON?
Clarification:
If I were to do data.layouts[0]["row_1"]["$ref"] wouldn't the result be #/questions/colorWhere I want it to be the actual object that it references. ie)
{name: 'What is your fav color?',
type: 'input'
}
Basically I need some way to do: foo(data, '#/questions/color') => the data that it is pointing to.
Thanks
Related
Currently I am trying to create a JSON object in java script which has an additional array containing all of the data that I currently posses:
src is a JSON object which before any code is run is equal to:
[
{
_id: new ObjectId("629ac43586b27bfd70337d06"),
Title: 'Test Poll',
Option: [ 'Test Option 1', 'Test Option 2', 'Test Option 3' ]
},
{
_id: new ObjectId("629afc9286b27bfd70337d09"),
Title: 'Test Poll 2',
Option: [ 'Test Option 1' ]
}
]
I need to reformat this object so that it is contained within a separate array which I am currently attempting to do with this line:
var context = { poll:src };
This results in a reformatting of the JSON object which I do not understand, after running this code context contains:
poll: [
{
_id: new ObjectId("629ac43586b27bfd70337d06"),
Title: 'Test Poll',
Option: [Array]
},
{
_id: new ObjectId("629afc9286b27bfd70337d09"),
Title: 'Test Poll 2',
Option: [Array]
}
]
It gets rid of the Option arrays and replaces them with [Array]. I need to keep these arrays and I am not sure what to change to fix this as I have tried looking elsewhere for answers. Does anyone have an idea of what is going on here?
Ok they are arrays I am just too new to realize that it would not print fully. I was attempting to use handlebars on these Option arrays to print the list and I was forgetting to use the implicit this for the variable name instead of just 'Option'.
Problem solved.
I have data in the format (input):
doSomething({
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
})
I managed to take out the doSomething part with the parenthesis as to load the function from the corresponding module with
expression.split('({',1)[0]
However using the loaded function with the rest, obtained with:
expression.split(temp+'(')[1].trim().replace(/\n+/g, '').slice(0, -1)
does not work because it should be an object and not a string. Hardcoding the data in does work as it is automatically read as an object.
My question is if there is any way of converting the string that I get from the user and convert it to an object. I have tried to convert it to a json object with JSON.parse but I get an unexpected character t at position 3. Also I have tried new Object(myString) but that did not work either.
What I would like is to have the body of the provided function as an object as if I would hard code it, so that the function can evaluate the different fields properly.
Is there any way to easily achieve that?
EDIT: the "output" would be:
{
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
}
as an object. This is the critical part because I have this already but as a string. However the function that uses this, is expecting an object. Like previously mentioned, hard coding this would work, as it is read as an object, but I am getting the input mentioned above as a string from the user.
Aside: I know eval is evil. The user could do by this certain injections. This is only one possibility to do this there are certain other ways.
I just added before "output =", cut from the input-string the "doSomething(" and the last ")". By this I have a normal command-line which I could execute by eval.
I highly not recommend to use eval this way; especially you don't
know what the user will do, so you don't know what could all happen
with your code and data.
let form = {first_name: 'Mickey', family_name: 'Mouse'};
let timeStart = (new Date()).toString();
let input = `doSomething({
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
})`;
let pos= "doSomething(".length;
input = 'output = ' + input.substr(pos, input.length-pos-1);
eval(input);
console.log(output);
I have a two sets of data, one formatted like so:
title: "Test Json",
showProgressBar: "top",
showQuestionNumbers: "off",
pages: [
{
questions: [
{
type: "",
name: "",
title: "",
hasOther: true,
isRequired: true,
colCount: 4,
choices: []
}
]
}
]
};
The other formatted like so:
{Answers: "“18-24”, “25-50”, “50+”",
Question: "How old are you?",
QuestionNumber: "1",
isRequired: "TRUE",
type: "radiogroup"}
This second set of data is multiple of these objects, which I am looping through using a forEach loop like so:
data.forEach((data, i)=>{
console.log(data)
// returns above object x3
})
What I want to do is use the first object and map values to the questions array using the values of the second object, so for example questions[0].type would be mapped to data.type.
I have managed to figure out mapping one object to the template doing this:
data.forEach((data, i)=>{
console.log(data)
questions[0].type = data.type
questions[0].name = data.Question
questions[0].title = data.Question
questions[0].choices = [data.Answers]
})
But this only maps the first object in the data array of objects, and I want to basically create a new template object based on the number of objects in the data array and create as many 'filled questions templates' as there is objects in data array
Any pointers and help would be lovely <3
Try this
data.forEach((data, i)=>{
console.log(data)
questions.push([{
type: data.type
name: data.Question
title: data.Question
choices: [data.Answers]
}])
})
Updated this answer with your additional question
I'm working on a an application that uses the survey building library surveyjs. I'm building a tool where users can input a survey JSON from that website into a form that is then sent as a string via an ajax request that triggers an AWS Lambda function. The lambda function takes the ajax request and inserts their survey into a MongoDB instance using mongoose.
When the string comes into the lambda function, it looks like this:
"{ pages: [ { name: 'page1', elements: [ { type: 'radiogroup', name: 'question1', title: 'IS THIS A SURVEY?', choices: [ { value: 'item1', text: 'Yes' }, { value: 'item2', text: 'No' } ] } ] } ]}"
And when I try to parse that string, I get this error:
Error: JSON Parse error: Expected '}'
I think it might have something to do with the JSON keys not being strings. I've also read that my use of single quotes could potentially be the problem, but I've exhausted my knowledge base.
Overall, my question is: How can I convert that string into a JSON object?
Thanks!
JSON strings need their string properties and values to be double-quoted. Use a regular expression and replace:
const originalStr = "{ pages: [ { name: 'page1', elements: [ { type: 'radiogroup', name: 'question1', title: 'IS THIS A SURVEY?', choices: [ { value: 'item1', text: 'Yes' }, { value: 'item2', text: 'No' } ] } ] } ]}";
const finalStr = originalStr
.replace(/'/g, '"')
.replace(/(\w+):/g, '"$1":');
console.log(JSON.parse(finalStr).pages);
That said, it would be better to fix whatever's serving the results in the first place, if at all possible.
If your lambda function is written using javascript then you can make use of eval to parse malformed JSON, however the eval'd string is evaluated as actual javascript within the current context so to get the result you have to set a variable within the string. Example:
var malformedJsonString = "{unquotedName: 'single quoted value'}";
eval("var myParsedJsonObject = "+malformedJsonString+";");
// myParsedJsonObject now contains your parsed JSON object
I need to import the following into a store but I am confused about the correct model or models I need to create.
here is an example of the JSON that is returned from my server. Basically its an array with 2 items, with an array in each. The field names are different in each.
I suspect I need to have more than one model and have a relationship but I am unsure where to start. Any ideas? Thanks
[
firstItems: [
{
name : "ProductA",
key: "XYXZ",
closed: true
},
{
name : "ProductB",
key: "AAA",
closed: false
}
],
secondItems : [
{
desc : "test2",
misc: "3333",
},
{
desc : "test1",
misc: "123"
}
]
]
What you have is not JSON, your opening and ending [] can become JSON by changing them to {} and then using the following models
Then you can model it as
// Abbreviated definitions of Models, it has changed starting at Ext 5
Ext.define('FirstItem', fields: ['name', 'key', 'closed'])
Ext.define('SecondItem', fields: ['desc', 'misc'])
Ext.define('TopLevel', {
hasMany: [
{model: 'FirstItem', name: 'firstItems'},
{model: 'SecondItem', name: 'secondItems'}
]
})
Use the reader for store's proxy, it will create appropriate model on load.
If you need to load already loaded json into the store use loadRawData but reader you will need in any case.