How do I iterate through this Firebase JSON? - json

This is the JSON content I have uploaded in Firebase database.
Now I need to access this in my Angular 2 app.
I am getting undefined and NaN while trying to access the objects.
{
"clients" : {
"clients" : {
"-Kdl_wRRkn7nJxgz4B54" : {
"balance" : "100.00",
"email" : "jdoe#gmail.com",
"firstName" : "John",
"lastName" : "Doe",
"phone" : "555-555-5555"
},
"-KdleehAQm0HgVFYdkUo" : {
"balance" : "350.00",
"email" : "stevesmith#gmail.com",
"firstName" : "Steve",
"lastName" : "Smith",
"phone" : "444-444-4444"
}
}
}
}
I am trying to access this here
export class ClientsComponent implements OnInit {
clients:any[];
totalOwed:number;
constructor(
public clientService:ClientService
) { }
ngOnInit() {
this.clientService.getClients().subscribe(clients => {
this.clients = clients;
console.log(this.clients);
this.getTotalOwed();
});
}
getTotalOwed(){
let total = 0;
for(let i = 0;i < this.clients.length;i++){
console.log(this.clients[i]);
total += parseFloat(this.clients[i].balance);
}
this.totalOwed = total;
console.log(this.totalOwed);
}
}

First off, you should re-structure your JSON, the structure below will be better for looping through, and a better practice. second, the reason you are getting not a number is because you are not accessing the balance key's value.
your code to loop through the data structure below would look something like:
for(let i = 0; i < this.clients.length(); i++) {
console.log(this.clients[i].balance)
}
and the JSON:
{
"clients" : [
{
"id" : "-Kdl_wRRkn7nJxgz4B54",
"balance" : "100.00",
"email" : "jdoe#gmail.com",
"firstName" : "John",
"lastName" : "Doe",
"phone" : "555-555-5555"
},
{
"id" : "-KdleehAQm0HgVFYdkUo",
"balance" : "350.00",
"email" : "stevesmith#gmail.com",
"firstName" : "Steve",
"lastName" : "Smith",
"phone" : "444-444-4444"
}
]
}

Related

Create view from 2 different collections in mongoDB

I want to create a view from 2 different collections(info1, info2) in mongodb.
I need to have LoginId, FirstName,LastName,Email from info1 collection and GroupName,Type,MachName from info2 collection. Connecting field between info1 and info2 collections are "GroupName" and "Group" respectively
Below the collection content:
info1:
{
"GroupName" : "TEST Group1",
"LoginId" : "login1",
"FirstName" : "John",
"LastName" : "deo",
"Email" : "john.deo#xyz.com"
}
{
"GroupName" : "TEST Group2",
"LoginId" : "login1",
"FirstName" : "John",
"LastName" : "deo",
"Email" : "john.deo#xyz.com"
}
{
"GroupName" : "TEST Group2",
"LoginId" : "login2",
"FirstName" : "Mark",
"LastName" : "Clan",
"Email" : "mark.clan#xyz.com"
}
info2:
{
"Group" : "TEST Group1",
"Type" : "DEV",
"ActiveFlag" : "True",
"MachName" : "group1.xyz.net",
}
{
"Group" : "TEST Group2",
"Type" : "DEV",
"ActiveFlag" : "True",
"MachName" : "group2.xyz.net",
}
{
"Group" : "TEST Group1",
"Type" : "UAT",
"ActiveFlag" : "True",
"MachName" : "group1.xyz.net",
}
{
"Group" : "TEST Group2",
"Type" : "UAT",
"ActiveFlag" : "True",
"MachName" : "group2.xyz.net",
}
I want to have output as below from the view.
Expected output:
{
"GroupName" : ["TEST Group1", "TEST Group2"]
"LoginId" : "login1",
"FirstName" : "John",
"LastName" : "deo",
"Email" : "john.deo#xyz.com",
"Type" : "DEV",
"MachName" : ["group1.xyz.net","group2.xyz.net"]
},
{
"GroupName" : ["TEST Group1", "TEST Group2"],
"LoginId" : "login1",
"FirstName" : "John",
"LastName" : "deo",
"Email" : "john.deo#xyz.com",
"Type" : "UAT",
"MachName" : ["group1.xyz.net","group2.xyz.net"]
},
{
"GroupName" : ["TEST Group2"],
"LoginId" : "login2",
"FirstName" : "Mark",
"LastName" : "Clan",
"Email" : "mark.clan#xyz.com",
"Type" : "DEV",
"MachName" : ["group2.xyz.net"]
},
{
"GroupName" : ["TEST Group2"]
"LoginId" : "login2",
"FirstName" : "Mark",
"LastName" : "Clan",
"Email" : "mark.clan#xyz.com",
"Type" : "UAT",
"MachName" : ["group2.xyz.net"]
}
I have tried with below but not able to get the expected output. Can someone please help me to have view which should give the expected output from the 2 collections(info1,info2)?
Tried code(not working):
db.getCollection("info1").aggregate(
[
{
"$lookup" : {
"from" : "info2",
"localField" : "GroupName",
"foreignField" : "Group",
"as" : "g"
}
} ,
{ $match: { $and: [ {"g.ActiveFlag" : "True"} ] } },
{
"$project" : {
"LoginId" : "$LoginId",
"FirstName" : "$FirstName",
"LastName" : "$LastName",
"Email" : "$Email",
"machName" : "$g.MachName"
}
}
],
{
"allowDiskUse" : false
}
);
Demo - https://mongoplayground.net/p/SX3xH1v_2wQ
Use $group
$first
$push
Groups input documents by the specified _id expression and for each distinct grouping, outputs a document. The _id field of each output document contains the unique group by value. The output documents can also contain computed fields that hold the values of some accumulator expression.
db.info1.aggregate([
{
"$lookup": {
"from": "info2",
"localField": "GroupName",
"foreignField": "Group",
"as": "g"
}
},
{
$match: {
$and: [
{
"g.ActiveFlag": "True"
}
]
}
},
{
$group: {
_id: null, // you can goup by LoginId if you want
GroupName: { $push: "$GroupName" },
MachName: { $push: { $first: "$g.MachName" } },
LoginId: { $first: "$LoginId" },
FirstName: { $first: "$FirstName" },
Email: { $first: "$Email" },
Type: { $first: { $first: "$g.Type" } },
}
}
])
Update
Updated Demo - https://mongoplayground.net/p/0AgT3FJIB6P
Use $unwind on g after lookup pipeline
{ $unwind: "$g" }
Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.
Demo - https://mongoplayground.net/p/IGzTzEbgfl0
$group: {
_id: {
Type: "$g.Type",
LoginId: "$LoginId"
}
// ....
}

Iterate Over JSON Object Obtained from Spring Boot Rest Application in Angular

I am getting a JSON response and I want to display the contents obtained from this response on my HTML page using angular.
ngOnInit() {
this.http.get(this.url)
.subscribe(response =>{
this.users = response.json();
});
}
Above code returns an Object of JSON which cause an error if iterated using ngFor.
I have tried some answers available on StackOverflow regarding this problem but they cause compilation errors or give no results.
Here is JSON Object I'm getting
{
"_embedded" : {
"users" : [ {
"name" : "Ahmad",
"role" : "Admin",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/1"
},
"user" : {
"href" : "http://localhost:8080/users/1"
}
}
}, {
"name" : "Umar",
"role" : "User",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/2"
},
"user" : {
"href" : "http://localhost:8080/users/2"
}
}
}, {
"name" : "Ali",
"role" : "Admin",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/3"
},
"user" : {
"href" : "http://localhost:8080/users/3"
}
}
}, {
"name" : "Waqas",
"role" : "User",
"_links" : {
"self" : {
"href" : "http://localhost:8080/users/4"
},
"user" : {
"href" : "http://localhost:8080/users/4"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/users{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/users"
},
"search" : {
"href" : "http://localhost:8080/users/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 4,
"totalPages" : 1,
"number" : 0
}
}
EDIT: HTML code with ngFor
<ul class="list-group">
<li
*ngFor="let user of users"
class="list-group-item">
{{ user }}
</li>
I am learning angular at the moment so please give some explanation with the answer.
You need to modify this
this.users = response.json();
to
this.users=response.json()._embedded.users
You need to modify this
this.users = response.json();
to
this.users = response.json()['_embedded']['users'];

Update deeply nested array in mongodb

I am trying to update field value in mongoose.
{
"_id" : ObjectId("5b62c772efedb6bd3f0c983a"),
"projectID" : ObjectId("0000000050e62416d0d75837"),
"__v" : 0,
"clientID" : ObjectId("00000000996b902b7c3f5efa"),
"inspection_data" : [
{
"pdf" : null,
"published" : "N",
"submissionTime" : ISODate("2018-08-02T08:57:08.532Z"),
"userID" : ObjectId("00000000cac68e3bc04643f7"),
"insSummary" : "inspected areas",
"insName" : "Infotech",
"_id" : ObjectId("5b62c772fa02622a18655e7b"),
"published_date" : ISODate("2018-08-02T08:57:22.041Z"),
"locationAspects" : [
{
"aspectname" : "Ground floor",
"_id" : ObjectId("5b62c772fa02622a18655e80"),
"comments" : [
{
"_id" : ObjectId("5b62c772fa02622a18655e81"),
"images" : [
{
"path" : "/uploads/inspection/00000000996b902b7c3f5efa/images/1533200242005-IpjLKH4XFWNEcHXa.png",
"img_name" : "1533200242005-IpjLKH4XFWNEcHXa.png",
"title" : "Fan",
"id" : "1"
},
{
"path" : "/uploads/inspection/00000000996b902b7c3f5efa/images/1533200242008-YN8IlA5yrMn3cBnn.png",
"img_name" : "1533200242008-YN8IlA5yrMn3cBnn.png",
"title" : "Box",
"id" : "2"
}
],
"comment" : [
"comment4"
],
"recommendation" : ""
}
]
}]
}
Here I want to update a title Fan in image array as table fan.
I tried $set but I don't know how to do for my db structure.
Kindly give some solution to this
**Updated:**
I tried this code:
mongo.inspection.update({"projectID" : mongoose.Types.ObjectId(req.body.project_id) },
{ "$set": {
"inspection_data.$[e1].locationAspects.$[e2].comments.$[e3].images.$[e4].title" : "TableFan"
}},
{ "arrayFilters": [
{ "e1._id": mongoose.Types.ObjectId(req.body.insId)},
{ "e2._id": mongoose.Types.ObjectId(req.body.aspectId)},
{ "e3._id": mongoose.Types.ObjectId(req.body.commentId)},
{ "e4.id": "1" }
]},function(err,response){
if(err){
console.log("error")
}
else{
console.log('Updated')
console.log(response)
}
})
db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } )
Its showing updated but in my db there is no change. Is any mistake I did ?
You can try with arrayFilters in mongodb
var mongoose = require('mongoose')
Temp.update(
{ "_id" : mongoose.Types.ObjectId("5b62c772efedb6bd3f0c983a") },
{ "$set": {
"inspection_data.$[e1].locationAspects.$[e2].comments.$[e3].images.$[e4].title": "TableFan"
}},
{ "arrayFilters": [
{ "e1._id": mongoose.Types.ObjectId("5b62c772fa02622a18655e7b") },
{ "e2._id": mongoose.Types.ObjectId("5b62c772fa02622a18655e80") },
{ "e3._id": mongoose.Types.ObjectId("5b62c772fa02622a18655e81") },
{ "e4.id": "1" }
]}
)
Note: You have to cast _id to ObjectId

Update a document in an array in MongoDB using webMethods

I have a requirement to a particular document in the arrayList, the sample JSON string for that is
{
"_id" : ObjectId("58b9339502be203f6b476664"),
"_docType" : "Test",
"type" : "mongoUpdate",
"createdDateTime" : "2017-03-03 09:12:53.080",
"contacts" : [
{
"firstName" : "FirstName",
"lastName" : "LastName",
"email" : "someName#email.com",
"contactType" : "Business.",
"phoneNumber" : "1234567890",
"createdDateTime" : "2017-03-03 09:13:04.229",
"lastModifiedDTM" : "2017-03-03 09:13:04.229",
},
{
"firstName" : "FirstName2",
"lastName" : "LastName2",
"email" : "someName#email.com2",
"contactType" : "Business2.",
"phoneNumber" : "1234567890",
"createdDateTime" : "2017-03-03 09:13:04.229",
"lastModifiedDTM" : "2017-03-03 09:13:04.229",
},
{
"firstName" : "FirstName3",
"lastName" : "LastName3",
"email" : "someName#email.com3",
"contactType" : "Business.3",
"phoneNumber" : "12345678903",
"createdDateTime" : "2017-03-03 09:13:04.229",
"lastModifiedDTM" : "2017-03-03 09:13:04.229",
}
]
}
Say I have to update one of the occurrence in the above json.
I have used the $set operation to update the above array and when I see the content in the mongo db I see the the whole array is replaced by single occurrence of contact.
the update command which I have used is
{$set:{"contacts":[{"firstName":"test0103)12","lastName":"test0103","email":"test0103","contactType":"test0103","phoneNumber":"test0103","createdDateTime":"test0103"}]}}
after executing this I see that the whole array list of 3 is replaced with the single instance of contacts.
and at the end I have the output as
"contacts" : [
{
"firstName" : "test0103)12",
"lastName" : "test0103",
"email" : "test0103",
"contactType" : "test0103",
"phoneNumber" : "test0103",
"createdDateTime" : "test0103"
}]
Here is the sample code
First find the document using _id. here collection I took is user
` User.findOne({'_id': 58b9339502be203f6b476664},(err,res) => {
if(res.contacts.length > 0){
var contacts = res.contacts;
var contactsList = [];
var contactobject = {};
// suppose you want to update the contact with firstname - FirstName2
contacts.map((contact,key)=>{
if(contact.firstName == "firstName2"{
contactobject.firstName = "Your updated name";
contactobject.lastName = "Your updated name";
// similary all values you want to update
// Then push to an array after updating new data
contactsList.push(contactObject);
}
else {
// if not the required contact to update
// simply push
contactsList.push(contact);
}
})
// After the map function , now update the new contacts
User.update({email:email},
{$set:{contacts: contactsList}},(err,result) => {
User.findOne({'_id':res._id}).then(updateuser => {
resolve(updateuser);
})
})
}
}) `
Try this , It works

Finding JSON objects in mongoDB

I'm trying to find objects using the built it queries and It just doesn't work..
My JSON file is something like this:
{ "Text1":
{
"id":"2"
},
"Text2":
{
"id":"2,3"
},
"Text3":
{
"id":"1"
}
}
And I write this db.myCollection.find({"id":2})
And it doesn't find anything.
When I write db.myCollection.find() it shows all the data as it should.
Anyone knows how to do it correctly?
Its hard to change the data-structure but as you want just your matching sub-document and you don't know where is your target sub-document (for example the query should be on Text1 or Text2 , ...) there is a good data structure for this:
{
"_id" : ObjectId("548dd9261a01c68fab8d67d7"),
"pair" : [
{
"id" : "2",
"key" : "Text1"
},
{
"id" : [
"2",
"3"
],
"key" : "Text2"
},
{
"id" : "1",
"key" : "Text3"
}
]
}
and your query is:
db.myCollection.findOne({'pair.id' : "2"} , {'pair.$':1, _id : -1}).pair // there is better ways (such as aggregation instead of above query)
as result you will have:
{
"0" : {
"id" : "2",
"key" : "Text1"
}
}
Update 1 (newbie way)
If you want all the document not just one use this
var result = [];
db.myCollection.find({'pair.id' : "2"} , {'pair.$':1, _id : -1}).forEach(function(item)
{
result.push(item.pair);
});
// the output will be in result
Update 2
Use this query to get all sub-documents
db.myCollection.aggregate
(
{ $unwind: '$pair' },
{ $match : {'pair.id' : "2"} }
).result
it produce output as
{
"0" : {
"_id" : ObjectId("548deb511a01c68fab8d67db"),
"pair" : {
"id" : "2",
"key" : "Text1"
}
},
"1" : {
"_id" : ObjectId("548deb511a01c68fab8d67db"),
"pair" : {
"id" : [
"2",
"3"
],
"key" : "Text2"
}
}
}
Since your are query specify a field in a subdocument this is what will work. see .find() documentation.
db.myCollection.find({"Text1.id" : "2"}, {"Text1.id": true})
{ "_id" : ObjectId("548dd798e2fa652e675af11d"), "Text1" : { "id" : "2" } }
If the query is on "Text1" or "Text2" the best thing to do here as mention in the accepted answer is changing you document structure. This can be easily done using the "Bulk" API.
var bulk = db.mycollection.initializeOrderedBulkOp(),
count = 0;
db.mycollection.find().forEach(function(doc) {
var pair = [];
for(var key in doc) {
if(key !== "_id") {
var id = doc[key]["id"].split(/[, ]/);
pair.push({"key": key, "id": id});
}
}
bulk.find({"_id": doc._id}).replaceOne({ "pair": pair });
count++; if (count % 300 == 0){
// Execute per 300 operations and re-Init
bulk.execute();
bulk = db.mycollection.initializeOrderedBulkOp();
}
})
// Clean up queues
if (count % 300 != 0 )
bulk.execute();
Your document now look like this:
{
"_id" : ObjectId("55edddc6602d0b4fd53a48d8"),
"pair" : [
{
"key" : "Text1",
"id" : [
"2"
]
},
{
"key" : "Text2",
"id" : [
"2",
"3"
]
},
{
"key" : "Text3",
"id" : [
"1"
]
}
]
}
Running the following query:
db.mycollection.aggregate([
{ "$project": {
"pair": {
"$setDifference": [
{ "$map": {
"input": "$pair",
"as": "pr",
"in": {
"$cond": [
{ "$setIsSubset": [ ["2"], "$$pr.id" ]},
"$$pr",
false
]
}
}},
[false]
]
}
}}
])
returns:
{
"_id" : ObjectId("55edddc6602d0b4fd53a48d8"),
"pair" : [
{
"key" : "Text1",
"id" : [
"2"
]
},
{
"key" : "Text2",
"id" : [
"2",
"3"
]
}
]
}