How to fetch nested relations on Kinvey - angularjs

So I'm working in an AngularJs app that is connected to a Kinvey backend. www.kinvey.com
In Kinvey we can fetch an entity and it's relations like this:
var promise = $kinvey.DataStore.get('events', 'event-id', {
relations : { location: 'locations' }
});
http://devcenter.kinvey.com/angular/guides/datastore#JoiningOperators
Relational Data / Fetching
The above is actually getting an event entity from the events collection and it's also fetching the data of the locations associated to it (which are in a different collection), so far so good we are able to retrieve an entity and it's associated entities ...
Now how could I retrieve the associations of those locations ?
In other words how can I retrieve nested associations ?
Thanks.

Like this:
$kinvey.DataStore.find('collection1', null, {
relations: {
name: "collection2",
"name.name": "collection3"
}
});
https://support.kinvey.com/discussion/201272198/nested-relations

Related

Get Firestore collection and sub-collection document data together

I have the following Firestore database structure in my Ionic 5 app.
Book(collection)
{bookID}(document with book fields)
Like (sub-collection)
{userID} (document name as user ID with fields)
Book collection has documentes and each document has a Like sub-collection. The document names of Like collection are user IDs who liked the book.
I am trying to do a query to get the latest books and at the same time trying to get the document from Like sub-collection to check if I have liked it.
async getBook(coll) {
snap = await this.afs.collection('Book').ref
.orderBy('createdDate', "desc")
.limit(10).get();
snap.docs.map(x => {
const data = x.data();
coll.push({
key: x.id,
data: data.data(),
like: this.getMyReaction(x.id)
});
}
async getMyReaction(key) {
const res = await this.afs.doc('Book/myUserID').ref.get();
if(res.exists) {
return res.data();
} else {
return 'notFound';
}
}
What I am doing here is calling the method getMyReaction() with each book ID and storing the promise in the like field. Later, I am reading the like value with async pipe in the HTML. This code is working perfectly but there is a little delay to get the like value as the promise is taking time to get resolved. Is there a solution to get sub-collection value at the same time I am getting the collection value?
Is there a solution to get sub-collection value at the same time I am getting the collection value?
Not without restructuring your data. Firestore queries can only consider documents in a single collection. The only exception to that is collection group queries, which lets you consider documents among all collections with the exact same name. What you're doing right now to "join" these two collections is probably about as effective as you'll get.
The only way you can turn this into a single query is by having another collection with the data pre-merged from the other two collections. This is actually kind of common on nosql databases, and is referred to as denormalization. But it's entirely up to you to decide if that's right for your use case.

How to create objects that have relationships when using Backand BaaS?

I am using Backand BaaS for my ionic app. My model consists of two tables:
1. Users
2. Trips
A one-to-many relationship has been established between 'Users' and 'Trips'.
'Users' has a collection field that is a collection of 'Trips' and 'Trips' has a owner field that is an object of 'Users'.
What is the correct way to create an object so that upon creating I am assigning the correct owner ('Users' object) to 'Trips' collection field ?
When POSTing a new Trip use this for the Trip Object
{
tripName:"asdf"
owner:1
}
In the users object it will look like this
{
id:1
fName:"david"
trips:[{__metadata: {id: 1}, tripName: "asdf"}]
}

Backbone.js Dynamic model creation based on JSON received from the server

I am trying to create a backbone client side application. I am receiving a list of json objects from the server on startup that will be a list of the possible tables exposed from the server, with their structure. E.g. Customers, Orders, Invoices, Employees
I want to create the models, collections and views dynamically based on the data I receive from the server.
Only when I receive the json on load will I know what the models should be and what the relationships between the models should be.
E.g. Customers structure might be Id, CustomerName, Address, Contact Numbers.
Order Structure might be Id, CustomerId, OrderDate, Amount
etc
By building Models, collections, views, controllers dynamically, I could in theory on startup point at another server who might give me a totally different set of tables e.g. : Movies, Actors etc.. with their structures.
Also, if additional fields are added I don't have to change the client side code again. E.g. Customer table might include a new field called ContactPerson
Please assist me as all the examples I saw on backbone is all based on statically defining the models on the client side up front. So create a model and collections and views for Customers, Orders, Invoices, Employees etc. etc.
Best wishes,
Andy
As already mentioned in the comments, Backbone models are dynamic by nature. So this is perfectly valid for example:
// A example dataset, this could be returned as JSON from the server
var jsonDataA = [
{
name: "Foo",
title: "Bar"
},
{
name: "a",
title: "b"
}
],
// A different example dataset
jsonDataB = [
{
make: "X",
model: "Y"
},
{
make: "Z",
model: "ZZ"
}
],
MyModel = Backbone.Model.extend({
/* Empty Model definition */
}),
MyCollection = Backbone.Collection.extend({
model: MyModel
}),
collection = new MyCollection();
collection.reset(jsonDataA);
console.log(collection.models);
collection.reset(jsonDataB);
console.log(collections.models);
Here I have reused the same Collection and Model definition to store completely different datasets.
One part is the raw data, the other part is its relations. You need to transport the metadata also, which contains the types and their relations. Model attributes will be populated automatically.
From your metadata a simple object can be constructed, where the keys describe one entity, for example:
var entites = {};
entities["Customer"] = Backbone.Model.extend({
/* Model definition based on metadata */
});
var parametersFromServer = {name: "John Doe"};
var customer = new entities["Customer"](parametersFromServer);
For building relations I would recommend using BackboneRelational plugin.

Backbone-relational hasmany best practices

I am new to Backbone-relational, I am not sure what is the right way to use HasMany.
I have a Parent model which have many children (by "many" I mean thousands of children). In order to avoid performance issue, I query children by their foreign key: /child/?parent=1, instead of create a huge list of child_ids in Parent. But seems this is not the way Backbone-relational work.
So I am wondering what is the right way to handle this.
1, Change my json api to include list of child id in parent, then send thousands of ids as Backbone-relational recommend:
url = function(models) {
return '/child/' + ( models ? 'set/' + _.pluck( models, 'id' ).join(';') + '/' : '');
}
// this will end up with a really long url: /child/set/1;2;3;4;...;9998;9999
2, override many method in Backbone-relational, let it handle this situation. My first thought is :
relations: [{
collectionOptions: function(model){
// I am not sure if I should use `this` to access my relation object
var relation = this;
return {
model: relation.relatedModel,
url: function(){
return relation.relatedModel.urlRoot + '?' + relation.collectionKey + '=' + model.id;
}
}
}
}]
// This seems work, but it can not be inherent by other model
// And in this case parent will have am empty children list at beginning.
// So parent.fetchRelated() won't fetch anything, I need call this url my self.
3, Only use Backbone-relational as a Store, then use Collection to manage relations.
4, Some other magic way or pattern or backbone framework
Thanks for help.
Here's the solution that I have going on my current project. Note that Project hasMany comments, events, files, and videos. Those relations and their reverse relations are defined on those models:
Entities.Project = Backbone.RelationalModel.extend({
updateRelation: function(relation) {
var id = this.get('id'),
collection = this.get(relation);
return collection.fetch({ data: $.param({ project_id: id }) });
}
});
I have the REST endpoint configured to take parameters that act as successive "WHERE" clauses. So project.updateRelation('comments') will send a request to /comments?project_id=4 I have some further logic on the server-side to filter out stuff the user has no right to see. (Laravel back-end, btw)

Extjs hasOne association local mode

I try to implement hasOne association in ExtJs 4. I use associationKey to load related model.
For example I have Person model. Some people may have spouse, so server side response with nested data like:
...
spouse: {
id: 5,
name: ...
...
}
Now when I use gettername function like:
var spouse = person.getSpouse()
If person has nested data like in example above it will return Person model object that is spouse of first one. But if there was no nested data, ExtJs try to load it dynamicly requesting the server. I want prevent this requests, can you help me?
Ok, so I thing I solve this myself. The reason is ExtJs tryed to load nested hasOne related data is because server sended
{
...
spouse_id: null,
spouse: null,
...
}
instead of:
{
...
spouse_id: null,
spouse: {},
...
}

Resources