How do I update only certain keys of existing objects in Mongodb? - javascript

So this is my case:
In my angular 8 application i create invoices. this is an invoice object:
{
"_id": {
"$oid": "5ea9ad58f65d8d49841362bd"
},
"details": [
{
"_id": "5ea1eff27a1fcb29c4e7d1b6",
"Client": "test",
"km": 88,
"Subject": "test",
"Location": "test",
"StartTime": "2020-04-27T09:00:00.000Z",
"EndTime": "2020-04-27T17:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "oekfokef",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 2,
"CreatedBy": "bob"
},
{
"_id": "5ea1f36297a9a315bc8ed078",
"Client": "test",
"km": 88,
"Subject": "ewfwefwe",
"Location": "fwefwefwefewfwefwef",
"StartTime": "2020-04-20T09:00:00.000Z",
"EndTime": "2020-04-20T17:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "wefwefewfwef",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 3,
"CreatedBy": "bob"
},
{
"_id": "5ea1f38d97a9a315bc8ed083",
"Client": "test2",
"km": 38,
"Subject": "test",
"Location": "test",
"StartTime": "2020-05-04T09:00:00.000Z",
"EndTime": "2020-05-04T16:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "test",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 4,
"CreatedBy": "bob"
}
],
"client": "Robin",
"hoursWorked": 75,
"kmsTravelled": 880,
"invoiceDate": "2020-04-29T16:37:44.948Z",
"paid": "false",
"subTotal": 3917.2,
"travelexpenses": 167.2,
"tax": 879.7,
"hoursCosts": 3750,
"total": 4796.9,
"createdBy": "bob",
"__v": 0
}
But during the use of the application, certain properties change value, like hoursWorked, total, kmTravelled, hourCosts and details. The updated objects get printed to the console. So whenever the user opens the component, i want it to post the whole object, but if an invoice with that Client name alread exists , only update those properties of each invoice per client.
the updated object is this.invoice:
this.invoice = {
client: element.Client,
hourCosts: (element.difference)*this.Client.price,
hoursWorked: (element.difference),
kmsTravelled: element.km,
travelexpenses: this.Client.kmPrice* element.km,
subTotal: (this.Client.kmPrice* element.km) + ((element.difference)*this.Client.price),
total: ((this.Client.kmPrice* element.km) + ((element.difference)*this.Client.price)) + ((this.Client.kmPrice* element.km)+((element.difference)*this.Client.price) * this.tax/100),
createdBy: this.userName,
details: this.details
}
So how do I go about this? Sorry for a quite vague question, but i stuck with this quite a while now. If you need more info please let me know

You could query by 'id' to search for specific values that have changed with something like: db.getCollection('hourCosts').find({_id:'5ea9ad58f65d8d49841362bd'})
Searching in a collection by id with .find() will be efficient. There's a really helpful mongoose doc page here.
Also, just clarifying, you're posting the full customer schema if the name is unique, otherwise updating the relevant invoices by 'client', is that correct? The doc page linked should be useful for most query types and you can create additional mongoose schemas for some added granularity in what content you change.

you can use mongoDB $set in the update command, example:
db.city.update({_id:ObjectId("584a13d5b65761be678d4dd4")}, {$set: {"citiName":"Jakarta Pusat"}})
make sure you are passing the _id as ObjectId
https://www.djamware.com/post/58578ab880aca715e80d3caf/mongodb-simple-update-document-example

Related

TypeORM Select Column from relation without using QueryBuilder

If anyway to select columns from relation without using querybuilder ???
This is my current query:
const areas = await this.areaRepository.find({
where: { ...isActive },
relations: ["division"],
});
Output :
{
"id": 1,
"version": 9,
"isActive": 1,
"createdBy": null,
"updatedBy": 1,
"createAt": "2022-04-18T15:42:12.000Z",
"updatedAt": "2022-09-23T11:04:53.000Z",
"name": "Dhaka",
"division": {
"id": 3,
"version": 1,
"isActive": 1,
"createdBy": null,
"updatedBy": null,
"createAt": "2022-04-18T15:42:00.000Z",
"updatedAt": "2022-04-18T15:42:00.000Z",
"name": "Dhaka"
}
},
But is there anything like:
const areas = await this.areaRepository.find({
select: ['id','division.id division_id']
where: { ...isActive },
relations: ["division"],
});
And the output will be:
{
"id": 1,
"division_id": 3
}
This is a duplicated question of: How to select fields from joined table using TypeORM repository?
You can check the answer here. Also this depends on which TypeOrm version you are currently using, as far as I know on version under 0.3 this doesn't work.

Split an array to individual array that have similar properties

I am creating chat functionality in my web app. I am using mysql to store data in a table with a userId and fromId columns. The userId is the message recepient while fromId is the sender.
So, what comes from the GET /messages endpoint looks something like this:
[
{
"id": 10,
"userId": 2,
"fromId": 4,
"message": "messsage",
"read": 0,
"createdAt": "2022-02-22T11:05:54.000Z",
"updatedAt": "2022-02-22T11:05:54.000Z",
"user.first": "Fourth",
"user.last": "NNe",
"user.email": "hello3#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 9,
"userId": 4,
"fromId": 2,
"message": "messsage",
"read": 0,
"createdAt": "2022-02-22T08:32:01.000Z",
"updatedAt": "2022-02-22T08:32:01.000Z",
"user.first": "Jane",
"user.last": "Doe",
"user.email": "hello1#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 8,
"userId": 2,
"fromId": 3,
"message": "messsage",
"read": 1,
"createdAt": "2022-02-22T08:31:52.000Z",
"updatedAt": "2022-02-22T08:31:52.000Z",
"user.first": "Third",
"user.last": "Tatu",
"user.email": "hello2#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 7,
"userId": 2,
"fromId": 4,
"message": "messsage",
"read": 1,
"createdAt": "2022-02-22T08:31:48.000Z",
"updatedAt": "2022-02-22T08:31:48.000Z",
"user.first": "Fourth",
"user.last": "NNe",
"user.email": "hello3#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 6,
"userId": 3,
"fromId": 2,
"message": "messsage",
"read": 0,
"createdAt": "2022-02-22T07:29:49.000Z",
"updatedAt": "2022-02-22T07:29:49.000Z",
"user.first": "Jane",
"user.last": "Doe",
"user.email": "hello1#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 5,
"userId": 2,
"fromId": 1,
"message": "messsage",
"read": 0,
"createdAt": "2022-02-22T07:29:48.000Z",
"updatedAt": "2022-02-22T07:29:48.000Z",
"user.first": "Joseph",
"user.last": "Mungai",
"user.email": "hello#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "admin"
},
{
"id": 4,
"userId": 1,
"fromId": 2,
"message": "messsage",
"read": 0,
"createdAt": "2022-02-22T07:20:37.000Z",
"updatedAt": "2022-02-22T07:20:37.000Z",
"user.first": "Jane",
"user.last": "Doe",
"user.email": "hello1#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "user"
},
{
"id": 2,
"userId": 2,
"fromId": 1,
"message": "If you have any questions or problems, you can ask them here.",
"read": 0,
"createdAt": "2022-02-22T07:16:04.000Z",
"updatedAt": "2022-02-22T07:16:04.000Z",
"user.first": "Joseph",
"user.last": "Mungai",
"user.email": "hello#feathersjs.com",
"user.phone": null,
"user.location": null,
"user.isVerified": 0,
"user.roles": "admin"
}
]
Now what I can't figure out is how to manipulate the array response to get different arrays of each conversation. I think I should use array.reduce method but I can't wrap my head around how to do that.
As shown in the image below for the UI, I would like the column marked 'names' in red, to have the different arrays of each conversation. And the column marked 'chat' in blue to have the contents of each of these conversations.
I am pretty sure this is doable, please help.
So you would need an array of messages which have both the sender Id and the recipient Id, or I think maybe a better approach could be to identify the objects with a conversationId which would make things a lot easier and you could group the results directly from sql. You could also group the results in your query by userId and fromId but that's out of the scope of this question. Anyway, this is what you are looking for
const mySegmentedArray = messageArray.reduce((finalArray, message)=>{
const addedConversation = finalArray.find(ma=>
((ma.user1 == message.userId && ma.user2 == message.fromId) ||
(ma.user1 == message.fromId && ma.user2 == message.userId))
if(addedConversation){
addedConversation.messages = [...addedConversation.messages, message]
}else{
finalArray = [...finalArray,
{
user1: message.userId,
user2: message.fromId,
messages: [message]}
}]
}
return finalArray
}, [])
Instead of a user having to fetch ALL the messages from the database for opening only 1 chat, I suggest to change the API. The /messages Api should accept userId parameter (the active user which is using the app), and fromId (the userId of a user you want to show messages from.
Whenever a user now clicks on any chat, you can do a GET request to server which would then return one single array of messages which you can directly display. No complex data manipulation, more maintainable code!.
Using SQL on serverside:
-- Pseudocode..
Select * from messageTable where userid=${userId} and fromId=${fromId};
The db is designed for receiving/filtering large amounts of data very fast and allows you to easily build up the data structure you like and is probably faster than doing it in javscript/node
Scaling
Think of a user having 100+ chats, it would be large amounts of data to fetch for him before being able to even open 1 chat! You could for example load the 5 "last active" chats on app start and then lazy load the other chats in the background. (or only load them on click.)
Later on you can finetune your API and provide an endpoint to maybe fetch a few chats at once but for beginning don't bother to make 1 Request per chat!.
You may also want to fetch only the latest x messages, when the app would be used multiple years, the data amount could become quiet large.

Not able to read below JSON using Angular 7

I was not able to read below mentioned received JSON from Rest API.
{
"details": {
"id": 21,
"gstin": "27AACCG7831Q1Z0",
"entityName": "GENX ENTERTAINMENT LIMITED",
"entityPan": "AACCG7831Q",
"entityTan": "abhishek123",
"entityCin": "null",
"entityWebsite": null,
"natureOfBusiness": null,
"constitution": "\"Public Limited Company\""
},
"addresses": [
{
"id": 22,
"buildingName": "\"Solitaire Corporate Park\"",
"location": null,
"street": null,
"buildingNo": "\"S-14\"",
"state": "bihar",
"district": "\"\"",
"city": "\"\"",
"flateNo": "\"1\"",
"pincode": "\"400093\"",
"isPrimary": false
}
]
}
I want to use above data received in JSON format into a form.
Your question is not clear, but you can pass this values to a form using this :
const formValues = JSON.parse(yourJson);
this.form.values = formValues;
See The Stakblitz Code Below
stackblit_sampleCode
Hope this helps..!

PouchDb - remove object inside document

I'm an Italian PouchDb and AngularJS Developer.
My json document is:
{
"_id": "6",
"_rev": "3-f7283d7683cd6fb15753f494aad1d49f",
"name": "Ivrea",
"owners": [
{
"owner_id": 1,
"name": "asdas",
"address": "asdas",
"gender": "Uomo",
"type": "Assente",
"notes": [
]
},
{
"owner_id": 2,
"name": "balbaba",
"address": "blabla",
"gender": "Uomo",
"type": "Assente",
"notes": [
]
}
]
}
and after an ng-click action, I will delete owner_id: 2 object inside _id: 6 document. In API reference I found only document delete action, but not how to delete object inside document.
Thanks for your reply!!
Alessandro
You just need to put() the main document back in the database after you remove an object from it. :)
db.get('foo').then(function (doc) {
delete doc.whatever;
return db.put(doc);
}).catch(function (err) { /* ... */ });

Request a complete response object instead of compact reponse object foursquare venues search api?

When we request a api call to foursquare for search venues of certain category
It returns a compact response not complete response because of which i am not able to get complete information about the place like if the place is open, price etc which is only returned in a complete response, can i get a complete response instead of compact response?? more info provided here.
Eg:
call:https://api.foursquare.com/v2/venues/search?ll=18.5308225,73.8474647&categoryId=4bf58dd8d48988d1e1931735&radius=1000&v=20131021&limit=1
Result:
{
"meta": {
"code": 200
},
"response": {
"venues": [{
"id": "4b975471f964a520c9ff34e3",
"name": "Yana Sizzler & Wok",
"contact": {
"phone": "+912066013897",
"formattedPhone": "+91 20 6601 3897"
},
"location": {
"address": "F C Road",
"lat": 18.52802688063791,
"lng": 73.84272476029567,
"distance": 589,
"cc": "IN",
"city": "Pune",
"state": "India",
"country": "India"
},
"categories": [{
"id": "4bf58dd8d48988d1df931735",
"name": "BBQ Joint",
"pluralName": "BBQ Joints",
"shortName": "BBQ",
"icon": {
"prefix": "https:\/\/ss1.4sqi.net\/img\/categories_v2\/food\/bbq_",
"suffix": ".png"
},
"primary": true
}],
"verified": false,
"restricted": true,
"stats": {
"checkinsCount": 542,
"usersCount": 402,
"tipCount": 19
},
"specials": {
"count": 0,
"items": []
},
"hereNow": {
"count": 0,
"groups": []
},
"referralId": "v-1386276988"
}]
}
}
But i am not getting informatiion like isOpen Price etc which we get in the complete response when we use explore.
The API does not support returning complete objects in venue search responses—you need to make a separate venue details call to get the information you're looking for. We recommend caching venue details (for up to 30 days) to avoid having to repeatedly calling this endpoint to retrieve this information that doesn't necessarily change that often.

Categories