how to create an array with subobjects of another array in angular - angularjs

Hi guys i am really stuck here,
i am creating a basic comment rating system which has subcomment feature
as you see in comments array > "subcomments" entries are objects and i want create array with them but i dont know how because theyre in an array.
i tried this:
this.CommentsArray.forEach((item, i) => {
if([item]["subcomments"] != undefined) {
[item]["subcomments"].forEach((subitem, i) => {
subitem = this.subCommentsArray[i];
})
}
but its not working. any suggestions ?
thanks..
edit:
my data structure is like that:
"comments" : {
"d4894e47181e43b7a0fb8b7699" : {
"commentDate" : "2018-08-13T19:49:49.814Z",
"commentPhotoExistence" : false,
"commentRate" : "3",
"commentRateState" : false,
"commentTagState" : false,
"commentText" : "",
"commentUID" : "d4894e47181e43b7a0fb8b7699",
"commenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"commenterUsername" : "Test2",
"subcomments" : {
"7c9f985d39334573b0211d18f1" : {
"subcommentDate" : "2018-09-01T11:57:10.523Z",
"subcommentText" : "EXAMPLE TEXT1",
"subcommentUID" : "7c9f985d39334573b0211d18f1",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
},
"a1197fb32eae483ba8e910a748" : {
"subcommentDate" : "2018-09-01T11:29:57.514Z",
"subcommentText" : "EXAMPLE TEST 2",
"subcommentUID" : "a1197fb32eae483ba8e910a748",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
},
"ad648a09a67c431c821bf8f290" : {
"subcommentDate" : "2018-09-01T11:57:01.452Z",
"subcommentText" : "example3",
"subcommentUID" : "ad648a09a67c431c821bf8f290",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
},
"f7682639d4584642a18a9a4ad7" : {
"subcommentDate" : "2018-09-02T15:41:38.162Z",
"subcommentText" : "example4",
"subcommentUID" : "f7682639d4584642a18a9a4ad7",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
}
}
}
the problem here is the subcomment id's are randomly added. in normally if it was Array i can use .forEach for use every item but there are random uid's between subcomments and subcomment properties. So all i want is create an array like including them, array will be like;
0: { "subcommentDate" : "2018-09-01T11:57:01.452Z",
"subcommentText" : "example3",
"subcommentUID" : "ad648a09a67c431c821bf8f290",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
}
1: {
"subcommentDate" : "2018-09-01T11:57:01.452Z",
"subcommentText" : "example3",
"subcommentUID" : "ad648a09a67c431c821bf8f290",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
}
2: {
"subcommentDate" : "2018-09-01T11:57:01.452Z",
"subcommentText" : "example3",
"subcommentUID" : "ad648a09a67c431c821bf8f290",
"subcommenterUID" : "17QYQbhmyQeIYocIZBwH8R7ojhg1",
"subcommenterUsername" : "Test2"
}
etc.

Your code is shadowing the variable i.
You're using is on your first line this.CommentsArray.forEach((item, i) => { then again on the subcomments.
this.CommentsArray.forEach((item, i) => {
if([item]["subcomments"] != undefined) {
[item]["subcomments"].forEach((subitem, z) => {
subitem = this.subCommentsArray[z];
})
}
});
But that's not the real problem. You're trying to iterate an object, not an array. The result will be coming back as;
{
"d48...669": {
"commentDate": '2019-08-13',
"subcomments": {
"7c9...8f1": {
},
"a11...748": {
}
}
}
}
You should iterate by the keys of the object;
Object.keys(this.CommentsArray).forEach(commentId => {
const comment = this.CommentsArray[commentId];
Object.keys(comment['subcomments']).forEach(subCommentId => {
const subComment = comment['subcomments'][subCommentId];
)};
});

Related

AngularJS count matching occurrences in an array

Objective: I want to count the occurrences of an id matching between arrays
The code below finds the match but we need to count the result
var arr1 = [
{
"image" : "FF815_1.jpg",
"id" : "NO"
}, {
"image" : "FF815_0.jpg",
"id" : "NO"
}, {
"image" : "FF815_4.jpg",
"id" : "NO"
}, {
"image" : "PIOJD_2.jpg",
"id" : "NO"
}, {
"image" : "PIOJD_4.jpg",
"id": "JD"
} ];
var arr2 = [
{
"image" : "FF815_1.jpg",
"id" : "NO"
}, {
"image" : "FF815_0.jpg",
"id" : "NO"
}, {
"image" : "FF815_4.jpg",
"id" : "NO"
}, {
"image" : "PIOJD_2.jpg",
"id" : "JD"
}, {
"image" : "PIOJD_4.jpg",
"id" : "JD"
} ];
angular.forEach(arr1, function(value1, key1) {
angular.forEach(arr2, function(value2, key2) {
if (value1.id === value2.id) {
console.log(value2.id);
}
});
});
Heres a fiddle: https://jsfiddle.net/62s0ae7v/
Just add a simple counter like :
var counter = 0;
angular.forEach(arr1, function(value1, key1) {
angular.forEach(arr2, function(value2, key2) {
if (value1.image === value2.image) {
console.log(value2.image);
counter++;
}
});
});
console.log(counter);

Update documents nested multiple levels in an array

I have this JSON structure in MongoDb and want to update changing a specific value of a particular item in a nested array. I would like to change the key targetAreaId from USER_MESSAGE to VISUAL_MESSAGE.
{
"_id" : "5cde9f482f2d5b924f492da2",
"scenario" : "SCENARIOX",
"mediaType" : "VISUAL",
"opCon" : "NORMAL",
"stepConfigs" : [
{
"stepType" : "STEPX",
"enabled" : true,
"configs" : [
{
"contentTemplateId" : "5cde9f472f2d5b924f492973",
"scope" : "STANDARD",
"key" : "CONTENT"
},
{
"priorityId" : "5cde9f472f2d5b924f49224f",
"scope" : "STANDARD",
"key" : "PRIORITY"
},
{
"targetAreaId" : "USER_MESSAGE",
"scope" : "STANDARD",
"key" : "TARGET_AREA"
}
],
"description" : "XPTO"
}
],
"scope" : "STANDARD" }
How can I do it in the same time?
EDIT
I am trying this way:
var cursor = db.getCollection('CollectionX').find({
"scenario": "SCENARIOX",
"stepConfigs.stepType": "STEPX",
"stepConfigs.configs.key": "TARGET_AREA"
});
if (cursor.hasNext()) {
var doc = cursor.next();
doc.stepConfigs.find(function(v,i) {
if (v.stepType == "STEPX") {
doc.stepConfigs[i].configs.find(function(w,j) {
if (w.key == "TARGET_AREA") {
var result = db.getCollection('CollectionX').update(
{ "_id" : doc._id },
{ "$set" : { doc.stepConfigs[i].configs[j].targetAreaId: "VISUAL_MESSAGE" }}
);
}
});
};
});
} else {
print("Step does not exist");
}
But the error below is occurring:
Error: Line 15: Unexpected token .
I don't think that's possible.
You can update the specific element you want using this query:
db.test_array.updateOne({}, {
$set: {
"stepConfigs.$[firstArray].configs.$[secondArray].targetAreaId": "VISUAL_MESSAGE"
}
}, {
arrayFilters: [{
"firstArray.stepType": "STEPX"
}, {
"secondArray.targetAreaId": "USER_MESSAGE"
}]
})
But pushing in the same array at the same time does render this (this was for the original model, but it's still the same problem, you can't $set and $push in the same array this way):
> db.test_array.updateOne({"step.type":"B"},{$push:{"step.$.configs":{"className":"something"}}, $set:{"step.$.configs.$[secondArray].targetAreaId":"TA-1"}},{arrayFilters:[{"secondArray.targetAreaId":"TA-2"}]})
2019-09-06T13:53:44.783+0200 E QUERY [js] WriteError: Updating the path 'step.$.configs.$[secondArray].targetAreaId' would create a conflict at 'step.$.configs' :

angularjs and elasticsearch js api, how to force GET instead of POST

I use elasticsearch javascript api with angularjs. This is working very good but i need to query the elasticsearch service through a middleware to filter dangerous request ( delete , update ). the middleware work with 'GET' but the API use by default 'POST' query.
According to the doc i can specify a parameter 'method' to use 'GET' query by the API :
API Conventions
It work with 'POST' but failed with 'GET',"GET' and i have an error :
Error: elasticQuery.search(...) is undefined
How can i do ? 'Get' can work with long and complexe query like this example bellow ?
this is how i try it :
return elasticQuery.search({
method : 'GET',
index: 'indexbotanic',
from: 0
size: 10,
body: {
"fields" : ["C_COLLECTIONCODE", "T_SCIENTIFICNAME", "T_SCIENTIFICNAMEAUTHORSHIP", "T_SPECIFICEPITHET", "T_KINGDOM", "T_PHYLUM", "T_CLASS_", "T_ORDER_", "T_FAMILY", "T_GENUS", "T_SUBGENUS", "T_VERNACULARNAME", "O_CATALOGNUMBER", "O_RECORDNUMBER", "O_CREATED", "O_SEX", "I_INSTITUTIONCODE", "D_DETERMINATIONID", "D_IDENTIFIEDBY", "M_IDENTIFIER", "E_RECORDNUMBER", "E_RECORDEDBY", "L_CONTINENT", "L_COUNTRY", "L_COUNTRYCODE", "L_COUNTY", "L_LOCALITY"],
"query" : {
"filtered" : {
"filter" : {
"and" : [{
"or" : [{
"term" : {
"L_CONTINENT" : "europe"
}
}
]
}, {
"or" : [{
"term" : {
"T_FAMILY" : "lamiaceae"
}
}
]
}, {
"or" : [{
"term" : {
"E_RECORDEDBY" : "balay, r."
}
}, {
"term" : {
"E_RECORDEDBY" : "boissier, p.e."
}
}
]
}, {
"or" : [{
"term" : {
"T_SCIENTIFICNAME" : "lamium amplexicaule"
}
}
]
}, {
"or" : [{
"term" : {
"T_GENUS" : "lamium"
}
}, {
"term" : {
"T_GENUS" : "betonica"
}
}
]
}
]
}
}
},
"highlight" : {
"pre_tags" : ["<strong>"],
"post_tags" : ["</strong>"],
"fields" : {
"C_COLLECTIONCODE" : {},
"O_CATALOGNUMBER" : {},
"O_RECORDNUMBER" : {},
"O_CREATED" : {},
"O_SEX" : {},
"D_DETERMINATIONID" : {},
"D_IDENTIFIEDBY" : {},
"E_EVENTID" : {},
"E_RECORDNUMBER" : {},
"E_RECORDEDBY" : {},
"L_CONTINENT" : {},
"L_COUNTRY" : {},
"L_COUNTRYCODE" : {},
"L_COUNTY" : {},
"L_LOCALITY" : {},
"T_SCIENTIFICNAME" : {},
"T_SCIENTIFICNAMEAUTHORSHIP" : {},
"T_SPECIFICEPITHET" : {},
"T_KINGDOM" : {},
"T_PHYLUM" : {},
"T_CLASS_" : {},
"T_ORDER_" : {},
"T_FAMILY" : {},
"T_GENUS" : {},
"T_SUBGENUS" : {},
"T_VERNACULARNAME" : {}
}
},
"aggs" : {
"L_CONTINENT_MISSING" : {
"missing" : {
"field" : "L_CONTINENT"
}
},
"O_SEX_MISSING" : {
"missing" : {
"field" : "O_SEX"
}
},
"I_INSTITUTIONCODE_MISSING" : {
"missing" : {
"field" : "I_INSTITUTIONCODE"
}
},
"T_TAXONRANK_MISSING" : {
"missing" : {
"field" : "T_TAXONRANK"
}
},
"D_TYPESTATUS_MISSING" : {
"missing" : {
"field" : "D_TYPESTATUS"
}
},
"O_HASMEDIA_MISSING" : {
"missing" : {
"field" : "O_HASMEDIA"
}
},
"T_SCIENTIFICNAME_MISSING" : {
"missing" : {
"field" : "T_SCIENTIFICNAME"
}
},
"T_FAMILY_MISSING" : {
"missing" : {
"field" : "T_FAMILY"
}
},
"T_GENUS_MISSING" : {
"missing" : {
"field" : "T_GENUS"
}
},
"E_RECORDEDBY_MISSING" : {
"missing" : {
"field" : "E_RECORDEDBY"
}
},
"L_CONTINENT" : {
"terms" : {
"field" : "L_CONTINENT",
"size" : 20
}
},
"O_SEX" : {
"terms" : {
"field" : "O_SEX",
"size" : 20
}
},
"I_INSTITUTIONCODE" : {
"terms" : {
"field" : "I_INSTITUTIONCODE",
"size" : 20
}
},
"T_TAXONRANK" : {
"terms" : {
"field" : "T_TAXONRANK",
"size" : 20
}
},
"D_TYPESTATUS" : {
"terms" : {
"field" : "D_TYPESTATUS",
"size" : 20
}
},
"O_HASMEDIA" : {
"terms" : {
"field" : "O_HASMEDIA",
"size" : 20
}
},
"T_SCIENTIFICNAME" : {
"terms" : {
"field" : "T_SCIENTIFICNAME",
"size" : 20
}
},
"T_FAMILY" : {
"terms" : {
"field" : "T_FAMILY",
"size" : 20
}
},
"T_GENUS" : {
"terms" : {
"field" : "T_GENUS",
"size" : 20
}
},
"E_RECORDEDBY" : {
"terms" : {
"field" : "E_RECORDEDBY",
"size" : 20
}
}
},
"sort" : "_score"
}
}).then(function (response) {
...
}
for example this work with GET :
curl -XGET 'http://localhost:9200/index/tablename/_search?pretty' -d '{
"query": {
"query_string": {
"query":"*keysearch*",
"fields": ["field1","field2","field3"]
}
}
}'
So how to force the api to send get with "-d '{ .... }' " ?
thanks a lot
Try to use this client: https://github.com/YousefED/elasticsearch.angular.simple and change POST into GET. I'm not sure which browsers support GET requests with a body though, you might be running into a limitation there.

elasticsearch run multiple different query in one call

I want to run 3 differents query (on the same index) with one call on elasticsearch service.
Is this possible ?
More elaborate question :
I make an autocomplete function in angularjs who search on 3 fields and display them :
"T_FAMILY" + "T_GENUS" + "T_SCIENTIFICNAME".
i was making only one query :
"query" : { "query_string" : { "query" : "T_FAMILY:" +value +" or T_GENUS:"+value+ " or T_SCIENTIFICNAME:"+value} }
// value is the user input and can contain wildcard *
but not revelant results.
Now i want to make 3 different query and sort each one by score. and finally get the 3 results and
merge them in an array and sort by score (i do this by my addKeyword() function).
var keywords = [];
keywords.push(val);
$scope.isHide.logo=true;
return elasticQuery.search({
index: $scope.domaine,
size: 20,
_source: false,
body: {
"fields" : ["T_FAMILY","T_GENUS","T_SCIENTIFICNAME"],
"query": { "bool" : {"must" : [{"wildcard" : { "T_FAMILY" : val }}]}},
"sort" : { "_score" : "desc" }
}
}).then(function (response){
addKeyword(response,keywords);
return elasticQuery.search({
index: $scope.domaine,
size: 20,
_source: false,
body: {
"fields" : ["T_FAMILY","T_GENUS","T_SCIENTIFICNAME"],
"query": {"bool" : {"must" : [{"wildcard" : { "T_GENUS" : val }}]}},
"sort" : { "_score" : "desc" }
}
}).then(function (response) {
addKeyword(response,keywords);
return elasticQuery.search({
index: $scope.domaine,
size: 20,
_source: false,
body: {
"fields" : ["T_FAMILY","T_GENUS","T_SCIENTIFICNAME"],
"query": {"bool" : {"must" : [{"wildcard" : { "T_SCIENTIFICNAME" : val }}]}},
"sort" : { "_score" : "desc" }
}
}).then(function (response) {
addKeyword(response,keywords);
return keywords;
});
return keywords;
});
});
I didn't find anything who help so i make 3 imbricated call of elastichsearch in my js code but it's not the best way maybe.
Thanks
it is possible to run differents queries in elasticsearch with "dis_max" :
return elasticQuery.search({
index: $scope.domaine,
size: 20,
_source: false,
body: {
//"min_score" : 0.50,
"fields" : ["T_FAMILY","T_GENUS","T_SCIENTIFICNAME"],
"highlight": {"pre_tags": ["<strong>"], "post_tags": ["</strong>"], "fields": { "T_FAMILY": {},"T_GENUS" : {}, "T_SCIENTIFICNAME": {} }},
"query" : {
"dis_max" : {
"tie_breaker" : 0.0,
"boost" : 1.0,
"queries" : [
{"wildcard" : { "T_FAMILY" : val }},
{"wildcard" : { "T_GENUS" : val }},
{"wildcard" : { "T_SCIENTIFICNAME" : val }}
]
}
},
"sort" : { "_score" : "desc" }
}
}).then(function (response){
return addKeywords(response,keywords);
});

How can I query in firebase using angularFire?

I have a simple structure in Firebase:
{
"categorias" : {
"categoria2" : {
"subcategorias" : {
"subcategoria4" : {
"nome" : "Subcategoria 4"
},
"subcategoria6" : {
"nome" : "Subcategoria 6"
},
"subcategoria5" : {
"nome" : "Subcategoria 5"
}
},
"icone" : "fa-cloud",
"nome" : "Categoria 2"
},
"categoria1" : {
"subcategorias" : {
"subcategoria1" : {
"nome" : "Subcategoria 1"
},
"subcategoria3" : {
"nome" : "Subcategoria 3"
},
"subcategoria2" : {
"nome" : "Subcategoria 2"
}
},
"icone" : "fa-bolt",
"nome" : "Categoria 1"
}
},
"locais" : {
"local1" : {
"subcategorias" : {
"subcategoria4" : true,
"subcategoria1" : true
},
"nome" : "Local 1",
"email" : "local1#loc1.com"
}
}
}
I need to list all "locais" that have "subcateria1: true" for example. I don't know how to do this because it is need "localId" but in query I don't know the localId. I just want all the "locais" that belongs to subcategoria1.
I'm using AngularFire.
I find the solution, but i don't know if it is the right way:
findBySubcategoria: function(subcategoriaId) {
var result = {};
locais.$on("value", function(snap){
var keys = snap.snapshot.value;
angular.forEach(keys, function(key, i){
if(key.subcategorias[subcategoriaId]){
result[i] = locais.$child(i);
}
});
});
return result;
}

Resources