backbonejs - fetching multiple model - backbone.js

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);
...
});

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);
}

mongodb append to an existing object

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" } }
)

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.

sencha touch routing extraparams kitchensink

I am trying to extend the routing in the Sencha Touch Kitchensink app as follows:
My data (in List store) are as follows:
{ category: 'fruit', str: 'tomato'},
{ category: 'fruit', str: 'green bean'},
{ category: 'vegetable', str: 'celery'},
{ category: 'vegetable', str: 'sprouts'},
{ category: 'notAVegetable', str: 'ketchup'},
{ category: 'notAVegetable', str: 'prune'}
I would like to show only those data selected by a particular category, such as "fruit"
In the Main.js controller, I am trying to do this by grabbing another parameter from the "List" node in the Demos TreeStore
routes: {
'demo/:id/:category': 'showViewById',
'menu/:id': 'showMenuById'
},
Where the showViewById action adds the extra parameter for use later
showViewById: function (id, category) {
var nav = this.getNav(),
view = nav.getStore().getNodeById(id);
console.log('view ' + id);
this.showView(view);
this.setCurrentDemo(view);
this.hideSheets();
// do stuff with category
},
I am trying to add and access 'category' as an extraParameter in my Demos.js store in the "List" tree node as follows:
{
text: 'List',
leaf: true,
id: 'list',
extraParams: {
category: 'fruit'
}
},
A few questions: Can I use an extraParameter to add this attribute to the Store? If so, how can I access it to use for my routing? I thought it would be available as metadata for my Demos store, but have not been able to access it.
Any alternatives short of creating multiple stores (one for "fruit", "vegetable", "notAVegetable," etc.) with filters on them to achieve the same thing?
TIA!

Backbone-relational between two models

By using Backbone-relational I would like to have the model task in this way:
task = {
id: 1
assigned_id: 2
name: 'read a book',
user: userModel
};
I did try this way (1) but the result is the following (2).
Any ideas?
(1)
var User = Backbone.RelationalModel.extend({
// urlRoot
});
var Task = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasOne,
key: 'user',
relatedModel: User
}
],
// urlRoot
});
(2)
task = {
id: 1
assigned_id: 2
name: 'read a book',
user: null // null instead of having something related to user model
};
Not sure what your the exact JSON is for your Task model, so I'm guessing here.
Backbone-relational is expecting either a fully nested model:
task = {
id: 1
assigned_id: 2
name: 'read a book',
user: {
name: 'Fred Rogers',
id: 42,
occupation: 'Hero'
}
};
Or a string/number, which it will assume to be the id of the related model:
task = {
id: 1
assigned_id: 2
name: 'read a book',
user: 42
};
I'm guessing you're hitting the second case, based on the null value you're getting for the user model.
When backbone-relational instantiates an instance of a model, and the related model is a "key" string/number, it will search its internal store of models to try to find a matching model. If it finds it, it sets that model as the value for the user property.
If it cannot find the model, it stashes the key in the model's relevant relation property model._relations[n].keyContents, and sets the user value to null.
It is at this point that you would use the fetchRelated function to get the related model from the datastore/API.
So, try calling task.fetchRelated() to get the related user model:
task.fetchRelated('user');

Resources