Excuse me for this simple problem - but I seem to miss something obvious.Any pointer would be a great help.
I have a JSON like
var whatever = [{
"key1" : { "text" : "text1","group" : "1" },
"key2" : { "text" : "text2","group" : "2" },
"key3" : { "text" : "text3","group" : "3" }
}];
I am trying to add another object(at start preferably) - but just couldn't get it to work.
var str = '{"text":"text0","group":"0"}';
var obj = JSON.parse(str);
whatever[0].put("key0",obj);
Getting the below error:
Uncaught TypeError: whatever[0].put is not a function
fiddle
There is no put function on the object. Use property instead of it. When you want to assign to a property which does not exist, it creates a new one and assigns the value to it.
whatever[0]["key0"] = obj;
What is related to at start preferably, there is no order for object properties. It is a wrong statement. If you want ordering try to think from the view of array of objects instead of array of object, which contains objects.
Code examples
const whatever = [{
"key1" : { "text" : "text1","group" : "1" },
"key2" : { "text" : "text2","group" : "2" },
"key3" : { "text" : "text3","group" : "3" }
}];
const str = '{ "text" : "text0", "group" : "0" }';
const obj = JSON.parse(str);
whatever[0]["key0"] = obj;
console.log(whatever);
Or use Object#assign
const whatever = [{
"key1" : { "text" : "text1","group" : "1" },
"key2" : { "text" : "text2","group" : "2" },
"key3" : { "text" : "text3","group" : "3" }
}];
const str = '{ "text" : "text0", "group" : "0" }';
const obj = JSON.parse(str);
Object.assign(whatever[0], { key0: obj }) // this will also change the object
console.log(whatever);
My suggestion is to use an array of objects, if you want something with order.
const whatever = [
{ "text" : "text1","group" : "1" },
{ "text" : "text2","group" : "2" },
{ "text" : "text3","group" : "3" }
];
const str = '{ "text" : "text0", "group" : "0" }';
const obj = JSON.parse(str);
// Add to the start
whatever.unshift(obj);
console.log(whatever);
// Add to the end
whatever.push(obj);
console.log(whatever);
maybe you want something like this
var whatever = [{
"key1" : { "text" : "text1","group" : "1" },
"key2" : { "text" : "text2","group" : "2" },
"key3" : { "text" : "text3","group" : "3" }
}];
Object.assign(whatever[0], {key4 : { "text" : "text4","group" : "4" }});
console.log(whatever);
Related
how to pull data with one common field and make nested json in javascript
I have an array like this :
var arr = [{
"date" : "2021-07-01",
"Subject" : "Math",
"index" : 1
},{
"date" : "2021-07-02",
"Subject" : "Social",
"index" : 2
},{
"date" : "2021-07-01",
"Subject" : "Science",
"index" : 3
},{
"date" : "2021-07-02",
"Subject" : "Economics",
"index" : 4
},{
"date" : "2021-07-01",
"Subject" : "English",
"index" : 5
},{
"date" : "2021-07-02",
"Subject" : "Computer",
"index" : 6
}]
In Result I want an array like that
arr = [{
date: "2021-07-01",
data : [{subject : "Math", "index" : 1},{subject : "Science", "index" : 3},{subject : "English", "index" : 5}]
},{
date: "2021-07-02",
data : [{subject : "Social", "index" : 2},{subject : "Economics", "index" : 4},{subject : "Computer", "index" : 6}]
}]
Here is what I am trying
var checkData = [];
var resultArr;
for(var i=0; i<arr.length; i++){
if(checkData.indexOf(arr[0].date) !== -1) {
// not getting data
}else{
checkData.push(arr[0].date);
resultArr.date = arr[0].date;
resultArr.data = {"index" : arr[0].index, "subject" : arr[0].subject};
}
}
Any help how can I achive this.
// fetch unique dates
const uniqueDates = arr.reduce((acc, rec) => {
if(acc.includes(rec.date))
return acc;
return [...acc, rec.date]
}, [])
//build your object
const result = uniqueDates.reduce((acc, rec)=> {
const data = arr.filter(i => i.date === rec).map(i => {
delete i.date
return i
})
return [...acc, {date: rec, data}]
}, [])
console.log(JSON.stringify(result, 2, 2))
I am having a problem on firebase functions. What I trying to do is when Items's child gets updated, then I want to get the value of Count and do further calculation, But what I am facing is that the firebase log console always shows an erreor "TypeError: Cannot read property 'val' of undefined".
JSON structure
"VTEST" : {
"A" : {
"Count" : 5,
"Items" : {
"item1" : "apple"
},
"NUMBER" : 5
},
"B" : {
"Count" : 8,
"Items" : {
"item1" : "orange;"
},
"NUMBER" : 3
},
"C" : {
"Count" : 10,
"Items" : {
"item1" : "grape"
},
"NUMBER" : 7
},
"D" : {
"Count" : 12,
"Items" : {
"item1" : "grava"
},
"NUMBER" : 10
},
"E" : {
"Count" : 15,
"Items" : {
"item1" : "fish"
},
"NUMBER" : 12
},
"F" : {
"Count" : 18,
"Items" : {
"item1" : "chicken;"
},
"NUMBER" : 8
}
}
My code:
exports.ItemCount = functions.database.ref('/VTEST/{ID}/Items').onUpdate((updateRef, context) => {
var childCount = updateRef.after.numChildren();
var newReference = updateRef.after.ref.parent.child('/Count');
var Count = newReference.val();
Count = Count + childCount;
return updateRef.ref.update({Count})
})
What I expect is the Count's value will be update, but it always show error : "TypeError: Cannot read property 'val' of undefined"
Can anyone tell me what am I doing wrong here, I don't get it.
The problem comes from the fact that a Reference does not have a val() method. You need to use the once() method to get the value of the corresponding database location.
The following adapted code should work:
exports.ItemCount = functions.database
.ref('/VTEST/{ID}/Items')
.onUpdate((updateRef, context) => {
var childCount = updateRef.after.numChildren();
var newReference = updateRef.after.ref.parent.child('/Count');
return newReference.once('value').then(dataSnapshot => {
var Count = dataSnapshot.val();
Count = Count + childCount;
return newReference.parent.update({ Count: Count });
});
});
However, depending on your exact requirements, you may decide to use a Transaction, see https://firebase.google.com/docs/database/web/read-and-write#save_data_as_transactions
I am having one input arrays,EX: let UPID = ["0","1","10"]. i have to check members.regularStudent whether given input values available or not ?, suppose not available means i have to push one array and return the results
My documents:
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
My Expected Output
[
"0",
"10"
]
My Code:
let UPID = ["0","1","10"]
db.Groups.find(
/*{
"members.regularStudent": { $nin: UPIDs }
}*/
)
.forEach(function(objects){
print(objects)
})
I had updated mycode, kindly see top on my question section, print(objects) means i am having the my objects, based on this variable can you update your answer,
** print(objects) **
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
You could use map method in combination with filter.
let UPID = ["0","1","10"];
let docs = [{ "_id" : "5bb20d7556db6915846da67f", "members" : { "regularStudent" : [ "3", "4" ] } },
{ "_id" : "5bb20d7556db6915846da55f", "members" : { "regularStudent" : [ "1", "2" ] } }]
let ids = [].concat(...docs.map(elem => elem.members.regularStudent));
console.log(UPID.filter(id => !ids.includes(id)));
Here I use forEach to iterate through the data to get all of the regularStudent data into one array then use filter to filter out the data from UPID array.
const UPID = ["0", "1" , "10"]
let data = [
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
]
let resularStudents = []
data.forEach(d => {
d.members.regularStudent.forEach(rs => {
resularStudents.push(rs)
})
})
var result = UPID.filter(
function(d) {
return this.indexOf(d) < 0;
},
resularStudents
);
console.log(result);
I am trying to validate array of objects using AJV schema validation. Below is the sample code
var Ajv = require('ajv');
var schemaValidator = Ajv();
var innerSchema = {
"type" : "object",
"properties" : {
"c" : {
"type" : "string"
},
"d" : {
"type" : "number"
}
},
"required" : ["c"]
}
var innerArraySchema = {
"type": "array",
"items" : {
"#ref": innerSchema
}
}
var schema = {
"type" : "object",
"properties" : {
"a" : {
"type" : "string"
},
"b" : {
"type" : "string"
},
"obj" : innerArraySchema
},
"required" : ["a"]
}
var testSchemaValidator = schemaValidator.compile(schema);
var data = {"a": "123","b" : "abc", "obj" : [{
"d" : "ankit"
}]}
var valid = testSchemaValidator(data);
console.log(valid);
if(!valid) {
console.log(testSchemaValidator.errors);
}
Is there something that I am missing here. I would not like to add the properties object inside the array definition itself.
Resolved the issue by using:
var innerArraySchema = {
"type": "array",
"items" : innerSchema
}
This question already has answers here:
Group array items using object
(19 answers)
Closed 6 years ago.
I want to modify a Javascript array, so that the elements having the same values for specifies properties merge into one object in a way that the other properties are kept as a comma-separated string, JSON string, or an array. Basically, I want to turn this:
[
{
"language" : "english",
"type" : "a",
"value" : "value1"
},
{
"language" : "english",
"type" : "a",
"value" : "value2"
},
{
"language" : "english",
"type" : "b",
"value" : "value3"
},
{
"language" : "spanish",
"type" : "a",
"value" : "valor1"
}
]
into this:
[
{
"language" : "english",
"type" : "a",
"value" : ["value1" , "value2"] // A Json string is welcome too
},
{
"language" : "english",
"type" : "b",
"value" : "value3"
},
{
"language" : "spanish",
"type" : "a",
"value" : "valor1"
}
]
I have tried iterating and filtering, then upserted the object as given in the snippet. But I wonder if there is a more elegant way to do that.
P.S EcmaScript6 and additional JS library suggestions are also welcome.
var originalArray = [
{
"language" : "english",
"type" : "a",
"value" : "value1"
},
{
"language" : "english",
"type" : "a",
"value" : "value2"
},
{
"language" : "english",
"type" : "b",
"value" : "value3"
},
{
"language" : "spanish",
"type" : "a",
"value" : "valor1"
}
];
var resultingArray = [];
// iterate through the original array
$.each(originalArray, function(i, val) {
// apply filter on key properties (i.e. language and type)
var result = resultingArray.filter(function( obj ) {
return (obj.language === val.language && obj.type === val.type);
});
// if a record exists, update its value
if (result.length === 1) {
result[0].value += (", " + val.value);
}
// else, add value
else if (result.length === 0) {
resultingArray.push(val);
}
// if multiple rows exist with same key property values...
else {
alert("Too many records with language '" + val.language + "' and type '" + val.type + "'");
}
});
console.log(JSON.stringify(resultingArray));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
This is what you need?
var baseData= [
{
"language" : "english",
"type" : "a",
"value" : "value1"
},
{
"language" : "english",
"type" : "a",
"value" : "value2"
},
{
"language" : "english",
"type" : "b",
"value" : "value3"
},
{
"language" : "spanish",
"type" : "a",
"value" : "valor1"
}
];
var newData = [];
baseData.forEach(function(item, index) {
if (newData.length === 0) {
newData.push(item);
} else {
var dIndex = -1;
newData.forEach(function(itm, idx) {
if (item.language === itm.language && item.type === itm.type) dIndex = idx;
});
if (dIndex !== -1) {
var oldValue = newData[dIndex].value;
if (typeof(oldValue).toString() === 'string') {
newData[dIndex].value = [oldValue, item.value];
}
} else {
newData.push(item);
}
}
});
console.log(newData);