I have a JavaScript object as shown below.
{
"28903218": {
"type": "group",
"prompt": "Cool, thanks! Now tell us about your child's day:",
"description": ""
},
"37742463": {
"type": "choice",
"prompt": "How does {{answer_28903220}} react in an unwelcome situation?",
"description": "(Such as not wanting to be in the car seat, when you're not in the room at bedtime, etc.)"
},
"30035493": {
"type": "choice",
"prompt": "Friday:",
"description": ""
},
}
I have a problem to read it. How can I get the 28903218 property's value?
surveyData.getQuestions().subscribe(
result => {
//here I need to get the "28903218" object's value
},
err => { },
() => { }
);
Assuming that you know 28903218:
var value = result["28903218"];
If you don't know it then you could loop through the properties until you find the desired one:
for (var prop in result) {
var value = result[prop];
}
Related
In my survey in SurveyJs, I'm attempting to implement a question with the type 'paneldynamic', which has the following structure:
{
type: "paneldynamic",
name: "9.2",
visible: false,
visibleIf: "{9.a.n} > 0",
title: "When did you give birth?",
enableIf: "{9.a.n} > 0",
requiredIf: "{9.a.n} > 0",
templateTitle: "Date of birth:",
templateElements: [
{
type: "text",
name: "9.2.1",
inputType: "date",
maxValueExpression: "today()",
titleLocation: 'hidden'
},
],
panelCount: "{9.a.n}"
}
where Question 9a is a number entry. I want the number of panels on this question to vary depending on the answer given to Q9a, but with this question structure the survey does not appear to bind the value of 9a to the actual panel count.
I've been unable to find anything in the documentation, and have tried variants such as "bindings: { "panelCount": "9.a.n" } which also don't seem to work.
How can I correctly set the variable panelCount property?
You may wish to create a custom function and calculate the number of panels based on another question answer. For example: https://plnkr.co/edit/iYNMt7JRPOh2dTOy.
Survey.Serializer.addProperty("paneldynamic", {
name: "panelCountExpression:expression",
onExecuteExpression: (obj, res) => {
if(res !== undefined) {
obj.panelCount = res;
}
}
});
var json = {
"pages": [
{
"name": "page1",
"elements": [
{
"type": "text",
"name": "question1",
"inputType":"number",
"min": 0,
"max": 5,
"defaultValue":"2"
},
{
"type": "paneldynamic",
"name": "question2",
"panelCountExpression":"{question1}",
"templateElements": [
{
"type": "text",
"name": "question3"
}]
}
]
}
],
};
I also recommend that you review the following:
Blogpost (the example was taken from it): SurveyJS Library — Calculate Properties and Hide Elements With Expressions and Functions.
Documentation: Conditional Logic and Dynamic Texts.
Thanks
I am trying to iterate through the array of objects but somehow not getting it right. Can somone please let me know where i am going wrong.
Here is the data
const response = {
"pass": 1,
"fail": 2,
"projects_all": [
{
"projects": [
{
"name": "Project1",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
},
{
"projects": [
{
"name": "Project2",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "FAIL",
}
},
{
"name": "Project3",
"status": "LIVE",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
}
]
}
And here is the code i tried
if(response) {
response?.projects_all?.forEach((projects) => {
projects.forEach(project) => {
if(project.previous !== null) {
//do something here
}
});
});
}
I am trying to iterate through this array of objects but it says projects not iterable. Any help is appreciated to make me understand where i am going wrong.
You were missing iterating over an array properly. A good idea is to format the JSON object that you plan to iterate over. So that you can see what are the arrays and objects, and at what hierarchy.
if (response) {
response?.projects_all?.forEach((project) => {
project?.projects?.forEach((project) => {
console.log(project?.name);
});
}
);
}
response?.projects_all?.forEach((projects) => {
This is the exact correct way to start the code. The problem that happens next is you apparently misunderstand what projects means in the following context
You do projects.forEach(project) as if you think projects is as array. projects is not an array at this point, it is an object that looks like this:
{
"projects": [
{
"name": "Project1",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
}
So I would actually want to do projects.projects.forEach(project => { ... }), or you could change the variable name from projects so it makes more sense to read.
First, determine what shape your response object currently has.
By using the ?. operator your essentially muting JS built in error reporting.
From the context, I assume your response actually looks like this:
console.log(response);
{
data: {
projects_all: [ ... ]
}
}
Therefore your existing code using response?.projects_all doesn't actually hit the projects_all property inside your response.
Can you try the following:
response.data.projects_all.forEach((project) => {
console.info("Project: ", project);
project.projects.forEach((project) => {
console.log(project, project?.name);
});
});
Alternatively, if you don't have a data key inside your response object, you can omit it in the loop:
response.data.projects_all.forEach((project) => {
console.info("Project: ", project);
project.projects.forEach((project) => {
console.log(project, project?.name);
});
});
I'm having trouble going through the data because of the ID 29450 and 3000 in this JSON data sample. My whole database has 1500 ID's. Now I want to print the data ['Id', 'Description', 'StartDate'] in the log from both ID's.
I'm a bit stuck now so hopefully somebody can help on the right track.
Thank you in advance. :)
const { Parser } = require('json2csv');
var fs = require('fs');
var fields = ['Id', 'Description', 'StartDate'];
var data = [
{
"29450": {
"Id": "29450",
"Description": "Lasser Niveau 4",
"StartDate": "0001-01-01T00:00:00",
"EndDate": "0001-01-01T00:00:00",
"Company": "",
"ResponsibilityCenter": "",
"FunctionGroup": "",
"City": "",
"Territory": "",
"Country": "",
"Attributes": {
"Name": {
"Description": "",
"Name": ""
},
"WERKTIJDEN": {
"Description": "Anders",
"Name": "Werktijden"
}
},
"RequestNo": ""
},
"3000": {
"Id": "3000",
"Description": "Lasser Niveau 4",
"StartDate": "0001-01-01T00:00:00",
"EndDate": "0001-01-01T00:00:00",
"Company": "",
"ResponsibilityCenter": "",
"FunctionGroup": "",
"City": "",
"Territory": "",
"Country": "",
"Attributes": {
"Name": {
"Description": "",
"Name": ""
},
"WERKTIJDEN": {
"Description": "Anders",
"Name": "Werktijden"
}
},
"RequestNo": ""
},
];
const json2csvParser = new Parser({fields, unwind: ['Id','Description','StartDate'], unwindBlank: true });
const csv = json2csvParser.parse(data);
fs.writeFile('file.csv', csv, function(err) {
if (err) throw err;
console.log('file saved');
});
Expected output:
Instead of...
const csv = json2csvParser.parse(data);
...use...
const csv = json2csvParser.parse(Object.keys(data[0]).map(key => data[0][key]));
Full explanation
Your data is in a strange format. It's an array of one object. I'm not sure if there would ever be another object in the array, but I have to assume that there won't be. So data[0] is the only relevant object here.
This data[0] is what I would call a index. It is an object that has properties that are the primary keys of the objects contained within. It's useful because you can access data[0]['1234'] to obtain the object with id '1234' in constant time. It's not clear if it would ever contain any other properties, but again, I'll assume that it won't because it looks a lot like an index.
You want to begin by getting all the keys of that one-and-only object of interest with Object.keys(data[0]). If you just map these keys to an array of the value of those properties, then you turn the index back into an regular unindexed array of objects -- and this is what json2csv expects as input.
The meat of the fix is a technique like this:
let unindexed = Object.keys(indexed).map(key => indexed[key])
It essentially turns this kind of structure...
var indexed = {
"29450": {
"Id": "29450",
"Description": "Lasser Niveau 4"
},
"3000": {
"Id": "3000",
"Description": "Lasser Niveau 4"
}
};
...into this kind of structure...
var unindexed = [
{
"Id": "29450",
"Description": "Lasser Niveau 4"
},
{
"Id": "3000",
"Description": "Lasser Niveau 4"
}
];
I think your problem is that you want to access the object but don't know its Id. You'll have to define how the object is to be distinguished from any other allowable properties in the containing object. Here's an example that just uses the first key as the one that specifies the object.
Note, this code is intended to be run in a node.js environment and requires the json2csv package npm i json2csv --save
const { Parser } = require('json2csv');
var fs = require('fs');
var fields = ['Id', 'Description', 'StartDate'];
var data = [
{
"29450": {
"Id": "29450",
"Description": "Lasser Niveau 4",
"StartDate": "0001-01-01T00:00:00"
},
"RequestNo": ""
},
{
"3000": {
"Id": "3000",
"Description": "Lasser Niveau 4",
"StartDate": "0001-01-01T00:00:00"
},
"RequestNo": ""
}
];
function getContainedObjectId(container) {
return Object.keys(container)[0];
}
var flattened = data.map(container => container[getContainedObjectId(container)]);
const json2csvParser = new Parser({ fields, unwind: ['Id', 'Description', 'StartDate'], unwindBlank: true });
const csv = json2csvParser.parse(flattened);
fs.writeFile('file.csv', csv, function (err) {
if (err) throw err;
console.log('file saved');
});
Here we rely on the ID being the first key. You'll have to define for us how to distinguish the ID from any other properties that may exist.
Here's another way that is potentially more robust. Search for the first key that looks like an integer (consists of digits 0-9) whose property name matches its value's Id property.
function getContainedObjectId(container) {
return Object.keys(container).filter(key => /^[0-9]+$/.test(key) && container[key].Id === key)[0];
}
I'm wondering how I can compare arrays of (nested) objects in Mongoose.
Considering the data below, I would like to get results when the name properties match. Could anyone help me with this?
Organisation.find( {
$or: [
{ "category_list": { $in: cat_list } },
{ "place_topics.data": { $in: place_tops } }
]
}
)
Let's say that this is the data stored in my MongoDB:
"category_list": [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
],
"place_topics": {
"data": [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
}
And let's say that these are the arrays I want to compare against (almost the same data):
let cat_list = [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
]
let place_tops = [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
When there are "multiple conditions" required for each array element is when you actually use $elemMatch, and in fact "need to" otherwise you don't match the correct element.
So to apply multiple conditions, you would rather make an array of conditions for $or instead of shortcuts with $in:
Organizations.find({
"$or": [].concat(
cat_list.map( c => ({ "category_list": { "$elemMatch": c } }) ),
place_tops.map( p => ({ "place_topics": { "$elemMatch": p } }) )
)
})
However, if you take a step back and think logically about it, you actually named one of the properties "id". This would generally imply in all good practice that the value is in fact ""unique".
Therefore, all you really should need to do is simply extract those values and stick with the original query form:
Organizations.find({
"$or": [
{ "category_list.id": { "$in": cat_list.map(c => c.id) } },
{ "place_topics.id": { "$in": place_tops.map(p => p.id) } }
]
})
So simply mapping both the values and the property to "match" onto the "id" value instead. This is a simple "dot notation" form that generally suffices when you have one condition per array element to test/match.
That is generally the most logical approach given the data, and you should apply which one of these actually suits the data conditions you need. For "multiple" use $elemMatch. But if you don't need multiple because there is a singular match, then simply do the singular match
Hi I'm currently creating an application to gather data form a website, and as I've researched you can used Json for that, now I have created a script to gather data, at first i have no problem with it, but when I cam across with a multi tree json i started having trouble.
here is my Json
{
"orders": [
{
"line_items": [
{
"id": 7660469767,
"name": "Personalised design - purple",
"properties": [
{
"name": "personalised text 1",
"value": "2"
},
{
"name": "personalised text 2",
"value": "Nuri &"
},
{
"name": "personalised text 3",
"value": "Samira"
}
],
}
]
}
]
}
I need to get the order.line_items.properties.value.
I tried this code but it says it does not work.
$.getJSON(order.json, function (data) {
$.each(data.orders.line_items.properties, function (index, value) {
$.each(this.value, function () {
console.log(this.text);
});
});
});
Can someone help me?
$.each(data.orders[0].line_items[0].properties, function (index, value) {
console.log(value.value);
});
Both orders and line_items are array, so it should have an access to array index first before accessing other object. And you don't have to use extra each in your code. The value above is an object for each properties. You can retrieve value there.