mongodb append to an existing object - arrays

here is my document, and I want to add a new field to it:
{
email_address: 'webmaster#example.com',
password: 'random_password',
first_name: 'John',
last_name: 'Doe',
website: {
main_title: 'My Blog Website',
main_url: 'http://www.example.com'
}
}
currently i am doing:
db.test.update({"email_address": "webmaster#example.com"},
{$set: {"website" : {"registrar": "namecheap"}}})
this erases the other fields inside website and just adds this new registrar field. how can I append to it?

You need to use dot-notation to set value to particular field of the sub-document, instead of setting the whole sub-document:
db.test.update(
{ "email_address": "webmaster#example.com" },
{ $set: { "website.registrar" : "namecheap" } }
)

Related

Pushing an array of objects into Firebase Collection Angular 8

I am trying to add a document into an array studyList in my users collection.
So i have a collection users where i have name, etc.. and studyList.
When i click on a button buy into a DocumentItemComponent i want to add that document into this studyList array.
My code works partially because it adds the document into the array but when i click on another document it changes the first one, it doesn't add another document.
This is my code for the adding function:
addToStudyList(user) {
const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.id}`);
const data: UserInterface = {
studyList: [{
title: this.document.title,
language: this.document.language,
description: this.document.description,
cover: this.document.cover,
category: this.document.category,
field: this.document.field,
id: this.document.id,
author: this.document.userUid,
urlDocument: this.document.urlDocument
}]
}
return userRef.set(data, {merge: true});
}
Can you help me, please?
Thank you! Have a good day!
There is no direct way to update an array inside a document, but if you are using Firestore, it provides arrayUnion and arrayRemove functions which you can use for adding/removing unique items in the array.
From firestore documentation https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array :
Try this:
userRef.update({
studyList: firebase.firestore.FieldValue.arrayUnion(data)
});
This is because when you declare:
studyList: [{
title: this.document.title,
language: this.document.language,
description: this.document.description,
cover: this.document.cover,
category: this.document.category,
field: this.document.field,
id: this.document.id,
author: this.document.userUid,
urlDocument: this.document.urlDocument
}]
in this piece of code you are assigning just one object to the the studyList array which overwrites the existing array, instead you should utilize the existing user studyList array and push your new object into it, something like this:
addToStudyList(user) {
const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.id}`);
user.studyList.push({
title: this.document.title,
language: this.document.language,
description: this.document.description,
cover: this.document.cover,
category: this.document.category,
field: this.document.field,
id: this.document.id,
author: this.document.userUid,
urlDocument: this.document.urlDocument
});
const data: UserInterface = {
studyList: user.studyList
}
return userRef.update(data);
}

How can I get an item in the redux store by a key?

Suppose I have a reducer defined which returns an array of objects which contain keys like an id or something. What is the a redux way of getting /finding a certain object with a certain id in the array. The array itself can contain several arrays:
{ items:[id:1,...],cases:{...}}
What is the redux way to go to find a record/ node by id?
The perfect redux way to store such a data would be to store them byId and allIds in an object in reducer.
In your case it would be:
{
items: {
byId : {
item1: {
id : 'item1',
details: {}
},
item2: {
id : 'item2',
details: {}
}
},
allIds: [ 'item1', 'item2' ],
},
cases: {
byId : {
case1: {
id : 'case1',
details: {}
},
case2: {
id : 'case2',
details: {}
}
},
allIds: [ 'case1', 'case2' ],
},
}
Ref: http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
This helps in keeping state normalized for both maintaining as well as using data.
This way makes it easier for iterating through all the array and render it or if we need to get any object just by it's id, then it'll be an O(1) operation, instead of iterating every time in complete array.
I'd use a library like lodash:
var fred = _.find(users, function(user) { return user.id === 1001; });
fiddle
It might be worth noting that it is seen as good practice to 'prefer objects over arrays' in the store (especially for large state trees); in this case you'd store your items in an object with (say) id as the key:
{
'1000': { name: 'apple', price: 10 },
'1001': { name: 'banana', price: 40 },
'1002': { name: 'pear', price: 50 },
}
This makes selection easier, however you have to arrange the shape of the state when loading.
there is no special way of doing this with redux. This is a plain JS task. I suppose you use react as well:
function mapStoreToProps(store) {
function findMyInterestingThingy(result, key) {
// assign anything you want to result
return result;
}
return {
myInterestingThingy: Object.keys(store).reduce(findMyInterestingThingy, {})
// you dont really need to use reduce. you can have any logic you want
};
}
export default connect(mapStoreToProps)(MyComponent)
regards

Angular-Formly Nested Model Not Updating

I am having an interesting issue with angular-formly. I am attempting to use the 'model' tag as shown below because my model is not flat.
{
'key': 'last',
'model': 'model.name',
'templateOptions: {}
}
However, I cannot update the model in a clean manner. Simply replacing model or even model.name with a matching model that contains the updated value does not cause the model to update the view.
var newModel = {
name: {
first: 'Gandalf',
last: 'The White'
}
};
self.model = {
name: {
first: 'Gandalf',
last: 'The Grey'
}
};
function setNewLastName() {
self.model = newModel;
}
setNewLastName();
However if I drill down to the specific property, it works as expected.
self.model.name.last = self.newModel.name.last;
Here is a link to a JSBin where the value updates using the drill-down method immediately above.
Drill-down JSBin
Another JSBin that attempts to update the model by assigning a new model that does not update.
Assign Model JSBin
Has anyone ran into this issue or can you see where I'm doing something wrong?
You replace the model for each key, therefore you never see the changes.
What you need to do is to match the model in the key itself.
vm.fields = [
{
key: 'name.first', // <-- HERE
type: 'input',
//model: vm.model.name, //Wrong
templateOptions: {
label: 'First Name'
}
},
{
key: 'name.first', // <-- AND HERE
type: 'input',
//model: vm.model.name, //Wrong
templateOptions: {
label: 'Last Name'
}
},
//...
];
See corrected example: http://jsbin.com/pupijoc/1/edit?js,console,output
UPDATE: Nested properties are also handled by fieldGroups
Se updated example: http://jsbin.com/pupijoc/3/edit?js,console,output

Breeze: getting collection of results that are wrapped in meta data object

I am attempting to use Breeze with AngularJS and a Web API back end which returns data in the following format:
API response format:
{
Count: 123,
Items: [
{
CustomerID: 1,
FirstName: "John",
Surname: "Smith",
// etc..
},
{
CustomerID: 2,
FirstName: "Bill",
Surname: "Jones",
// etc..
},
{
// 23 more Customer records...
}
],
NextPageLink: "http://localhost/web/api/customers?$skip=25"
}
I have manually set up the Customer entity in the metaDataStore following the example on the Breeze.js website http://www.breezejs.com/documentation/metadata-hand-depth:
function addCustomer() {
addType({
shortName: "Customer",
defaultResourceName: "customers",
dataProperties: {
CustomerID: { type: ID, isPartOfKey: true },
FirstName: { max: 50 },
Surname: { max: 50 },
// a bunch more properties
}
});
}
My code to query the "customers" endpoint looks like this:
function getCustomers(){
var customers = manager.getEntities('Customer');
return breeze.EntityQuery.from('customers')
.using(manager).execute()
.then(function(data){
return data.results; // breakpoint here is reached
});
}
The query successfully executes, as when I put a breakpoint where indicated, the data object is there but the data.results property is an array containing what looks like a single Customer entity that is empty. See screenshot:
I suspect that this is due to the fact the the back end is returning the collection as the Items property of a wrapper object.
My question then is: assuming I am unable to change the response from the back end API, how do I tell Breeze that my Customer entities are actually contained in the results.Items property?
You can build your own custom JsonResultsAdapter to do this.
See http://www.breezejs.com/documentation/mapping-json for more details.
We also have a sample that shows a custom adapter in action with a 3rd party back end.
Hope this helps.

backbonejs - fetching multiple model

i'm novice in backbonejs and i'm doing some project that includes fetching and displaying friends list. for this project i'm using parse.com as database. but i'm stocked at this point.
for example: i have following data's in user and friends models.
var user = [
{
id: 'x1',
firstname: 'Ashik',
lastname: 'shrestha',
phone: '12321321',
mobile: '123213',
email: 'xyz#gmail.com'
},
{
id: 'x2',
firstname: 'rokesh',
lastname: 'shrestha',
phone: '12321321',
mobile: '123213',
email: 'rokesh#gmail.com'
},
];
var friends = [
{
user_id: 'x1',
user_friend_id: 'x2'
},
{
user_id: 'x1',
user_friend_id: 'x4'
},
{
user_id: 'x1',
user_friend_id: 'x10'
},
{
user_id: 'x2',
user_friend_id: 'x25'
}
];
// collections
var userCollection = Backbone.collection.extend({
model: user
});
var friendListCollection = Backbone.collection.extend({
model: friends
});
var friends = new friendListCollection();
now what i want?
when i fetch friends collection object, i want to get friends list of user with their details.
example::
friends.fetch({
success: function(ob){
var ob =ob.toJSON();
// i want ob to be like
[
{
id: 'x2',
firstname: 'rokesh',
lastname: 'shrestha',
phone: '12321321',
mobile: '123213',
email: 'rokesh#gmail.com'
},
{
id: 'x4',
firstname: 'rokesh',
lastname: 'shrestha',
phone: '12321321',
mobile: '123213',
email: 'rokesh#gmail.com'
},
{
id: 'xx10',
firstname: 'rokesh',
lastname: 'shrestha',
phone: '12321321',
mobile: '123213',
email: 'rokesh#gmail.com'
},
]
}
});
should i create new collection to relate them or is there any other way to do this??
Thanks in advance!
To use the least of server requests to gain a better performance and less presure on server side, I would suggest you to add this logic on your server-side rather than here on client-side. e.g. When fetching with parameters like ?detail=true, the server then return simple information with detailed data, otherwise only return simple information.
If you have a good reason to seperate them into different Collections, you have to fetch those collections consequently.
Assuming you do not wish to change your data structure, you can use BackboneJS' model's idAttribute property, to retrieve a specific model from a collection by a specific key, usually an "id".
When you define your model, you should also define the idAttribute for the model, which will later allows your to access it from the collection, by the value of this field.
When a Backbone collection is synced, all models are parsed according to their defined structure, adding administrative functionality on top of their data.
Consider the following example:
var myModel = Backbone.Model.extend({
idAttribute: "id"
...
});
var myCollection = Backbone.Collection.extend({
model: myModel
...
});
Once myCollection holds one or more "myModel"(s) you can then simply use the following:
var myModelFromMyCollection = myCollection.get(id);
the idAttribute of the model can by any of the model's fields...
For your use case, lets assume both friendListCollection and userCollection are already available and have models in them, consider the following code to get the full details of each friend from it's user model like so:
friendListCollection.each(function(friendModel) {
var friendFullDetailsFromUsersCollection = userCollection.get(friendModel.id);
console.log(friendFullDetailsFromUsersCollection);
...
});

Resources