This is a migrated thread and some comments may be shown as answers.

Accessing Everlive with Kendo DataSource

25 Answers 728 Views
General Discussion
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Kelly
Top achievements
Rank 1
Kelly asked on 29 Dec 2013, 01:19 AM
Hello,
Is there a way to use the equivalent of an Everlive query.select in a Kendo UI DataSource, in order to retrieve a subset of fields?

Thank you,

Kelly

25 Answers, 1 is accepted

Sort by
0
Anton Dobrev
Telerik team
answered on 01 Jan 2014, 06:34 PM
Hello Kelly,

The Kendo UI DataSource integrates seamlessly with Everlive. More on this can be read here. However, the default behavior is to retrieve all fields of an item. Then you can easily manage which fields to show, to enable for editing or to hide in the UI using the various configuration options of the Kendo UI widgets.

We have come with the following workaround for retrieving only the fields that you are interested in, using the REST API. The basic steps are explained below:

In the ‘fieldsExp’ object are all the fields of the content type we would like to retrieve.

var fieldsExp = {  "Description" : 1, "Username" : 1  };

We initialize our data source component with an explicit ‘transport’ configuration (without using the Everlive dialect) and configure the request headers that are going to be sent to the server.

transport: {
    read: {
        dataType: "json",
        contentType: "application/json",
        beforeSend: function (xhr) {
            xhr.setRequestHeader("X-Everlive-Fields",  JSON.stringify(fieldsExp))
        },
    }
},

The data from the response is parsed into a model that is going to be passed to a Kendo UI grid.

schema: {
     parse: function (response) {
         var products = [];
         var data = response.Result;
         for (var i = 0; i < data.length; i++) {
             var product = {
                 Username: data[i].Username,
                 Description: data[i].Description
             };
              products.push(product);
          }
          return products;
         }
}

The final step is to initialize a grid and visualize the data.

$("#grid-container").kendoGrid({
    dataSource: dataSource,
    columns: [{
          field: "Username",
          title: "Username field",
          }, {
          field: "Description",
          title: "Description field"
          }
       ]
});

Please, let us know if this workaround works for you.


Regards,
Anton Dobrev
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Emmanuel
Top achievements
Rank 1
answered on 19 May 2014, 01:32 PM
Hello,

I want to use the date source with a relationship 1-n , how can I achieve this  ?
In you example, how can I access to the object Cities of the products ? 

And also, I can filter on this ?
here is my example  :

I have a table Activity, and a table UserAffectationStatus which make the link between my activity and my users (1-N)
How can I get all the activity of my current user ? 

Thank you in advance for you help,




0
Anton Dobrev
Telerik team
answered on 20 May 2014, 01:53 PM
Hello Marc,

Telerik Backend Services provide several means for resolving the related items. Choosing the best of them depends on how the UI is bound to the data source and the schema of the data store.
For instance, continuing on the previous example, you can set a header with an expand expression that will expand the Cities field:
var expandExpression = {
    "Cities": true
};
var dataSource = new kendo.data.DataSource({
    type: "everlive",
    transport: {
        typeName: "Products",
        read: {
            beforeSend: function (xhr) {
                xhr.setRequestHeader("X-Everlive-Expand", JSON.stringify(expandExpression));
            }
        }
    },
    schema: {
        model: {
            id: Everlive.idField
        }
    }
});

In regard to your second question.

Could you please elaborate a bit more on the data schema? Taking the activities for the current user seems to be as straightforward as applying a filter that matches the Id of the current user and the UserId field in the other table.

In addition, we always recommend to developers to embed the data instead of referencing it when this is applicable. The Backend Services data store is a NoSQL, document-based database, and a great amount of denormalization is allowed.

Briefly said, NoSQL databases are designed for a greater horizontal scalability and much faster performance. One tradeoff for the increased performance comparing to relational databases happens to be the lack of JOIN queries.
Operating with the aforementioned utilities on very large datasets is going to be slow, that is why some limitations are imposed on their usage. They are neither a fully operational replacement of JOIN queries, nor are intended to be.

That is why we recommend to handle these specifics design-time and to save documents with pre-joined data in them where applicable and depending of the data access patterns of your app.


Regards,
Anton Dobrev
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Daniel Plomp
Top achievements
Rank 2
answered on 16 Jan 2015, 09:20 AM
Hi Anton,

I'm pretty new to the Telerik Platform and especially NoSQL.
Can you elaborate a bit more on how to setup a RDMS relation like this:

A Family can have one or more Persons
A Person can have one Family

So that would be a many-to-many relationship.

Currently I configured my backend service project to pick a Family with a Person and not picking multiple Persons with a Family.
Does that makes sense?

Not sure what the best practice would be.

Regarding to the example above, I tried it and it works okay when using the Expand Fields.
Inside my KendoUI Grid I use this code to display the Fullname property of the Family field (which is expanded).

$("#grid").kendoGrid({
   columns: [{
      field: "Firstname",
      title: "Firstname"
   },
   {
      field: "Family.Fullname",
      title: "Family"
   }
]
});

Is that the right approach?

Thanks,
Daniel
0
Anton Dobrev
Telerik team
answered on 19 Jan 2015, 04:01 PM
Hi,

@Daniel
Thank you for posting to the Telerik Developer Forums.

In brief, yes, the proposed approach is acceptable in NoSQL databases. Please, allow me to specify that depending on the way you are going to retrieve the data, you can choose different approaches for the schema design. For instance, in NoSQL databases a common approach is to prefer embedding the children items in the parent item instead of using a reference to them. In your case this means that the family members are in the same entity Family and not in a separate entities in a Person content type. This is the more natural way to save data in NoSQL and a prerequisite to make greater benefit from the NoSQL advantages.

Consider the following structure of a Family entity:
{
    "Id": "Guid-Here",
    "Name": "The Family",
    "Address": "1, The address Str.",
    "Zip Code": "11111",
    "Members": [{
        "Name": "The Father",
        "Gender": "Male",
        "Occupation": "Consumer retailing"
    }, {
        "Name": "The Mother",
        "Gender": "Female",
        "Occupation": "Automotive industry"
    }, {
        "Name": "The Son",
        "Gender": "Male",
        "Occupation": "College"
    }]
}

If you are going to retrieve the data for a family always with expanding the parent item, you might consider embedding the items in the parent item.

You can read more about this matter in the following article and the materials referenced in it.

If the Person entities are also needed in other content types or views of you application (for example, you need to fetch the Persons in a separate view), it might be better to leave them in a separate content type and use a reference to them in the Family. In addition, frequently, it is better to hold also a reference to the Family in each Person, if you need to browse the Persons and determine fast to which family they belong.

Note also the Permissions for a content type and who is able to make CRUD operations over the content type - separate content types will give you a flexible Type permissions security pattern. You can also use item-level permissions or and specify that only members of the family can write to this item. In both approaches you can apply Role-based security and specify which roles can operate with the data subject to restrictions.

Bottom line is that depending on the Security and data retrieval patterns you need to apply in your app, you can determine a suitable data schema.

Please, let me know if this is helpful for you and if you have questions.

Best regards,
Anton Dobrev
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Daniel Plomp
Top achievements
Rank 2
answered on 19 Jan 2015, 07:34 PM
Hi Anton,

Thanks for the follow up. That make things more clear!

I'm still doubting whether to use the NoSQL approach or Entity Framework with WebAPI, since I'm not quite convinced if I can do the same with the Telerik Backend Services.

If you have time, maybe you can convince me, if you think the Telerik solution would fit.

Best,
Daniel
0
Anton Dobrev
Telerik team
answered on 21 Jan 2015, 01:49 PM
Hi Daniel,

Both approaches are very good fit for the scenario you explained above and each of them has advantages on its own.

Using Telerik Backend Services will give you the scalability of the cloud and the NoSQL databases without the need to build your own REST API and deploying it to your own servers. Once you have determined the data usage patterns of your app and use it to design your schema accordingly, you can continue very fast with the developing of the business logic and UI.

If you choose the Web API approach, you can still use the other services provided by Backend Services like Push Notifications, Responsive Images, etc. in your mobile app.

In addition, Telerik Data Access could greatly help you with building your own RESTful layer on top of a relational database. Please, consult this article if you are interested in this.

Let me know if you have further questions, I will be happy to help.

Best regards,
Anton Dobrev
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Daniel Plomp
Top achievements
Rank 2
answered on 21 Jan 2015, 03:32 PM
Hi Anton,

Thanks.
If I want to create a MVC web application, rather than a mobile app, would it also be possible to use the .NET SDK, rather than the Javascript SDK? I'm currently more into .NET, so that would be preferred.

Best,
Daniel
0
Anton Dobrev
Telerik team
answered on 23 Jan 2015, 02:21 PM
@Daniel

Yes, you can use the .NET SDK in ASP.NET MVC application, this is the suggested approach as well. Currently we do not have a dedicated sample, but hopefully the documentation articles will help you get started. 

Please, do not hesitate to contact us should you have any further questions.

Regards,
Anton Dobrev
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Romel
Top achievements
Rank 1
answered on 06 May 2015, 10:25 AM

 Hi Anton,

Were using this code previously (see code below) but suddenly today its not working. Were thinking that it was have a connection on the Screen Builder says "Please be informed that as we move to v1 of Screen Builder, all projects created with the old Beta versions of Screen Builder won't open in the new versions. You can still edit, simulate, build and deploy the old projects with AppBuilder."

Because were using the same Backend Service that what we are using now.

Any suggestion and ideas that can help us because we're using it on our demo.

 

Thanks,

Romel

var expandExpression = {
    "Cities": true
};
var dataSource = new kendo.data.DataSource({
    type: "everlive",
    transport: {
        typeName: "Products",
        read: {
            beforeSend: function (xhr) {
                xhr.setRequestHeader("X-Everlive-Expand", JSON.stringify(expandExpression));
            }
        }
    },
    schema: {
        model: {
            id: Everlive.idField
        }
    }
});

 

 

 

 

 

 

0
Romel
Top achievements
Rank 1
answered on 07 May 2015, 07:18 AM

Hi Anton,

Also tried to create a sample code in kendo please check we need this to demo our app.

http://dojo.telerik.com/ahACA

Thanks,

Romel

0
Vasil
Telerik team
answered on 07 May 2015, 09:52 AM
Hello Romel,

We have updated the way the kendo datasource works so you now can pass headers directly to the read option instead of settings them on the xhrRequest. However it seems we might have missed to update the documentation. 

The updated configuration should be something similar to this:
      var apiKey = "YOUR-API-KEY";
    var typeName = "CONTENT-TYPE-NAME";
    var expandExpression = {};
    var el = new Everlive(apiKey);
     
    var datasource = new kendo.data.DataSource({
        type: "everlive",
        transport: {
            typeName: typeName,
            read: {
                headers: {
                  "X-Everlive-Expand": JSON.stringify(expandExpression)
                }
            }
        },
        schema: {
            model: {
                id: Everlive.idField,
            },
        }
    });
 
    datasource.fetch(function() {
      console.log(datasource.data());
    });

I apologize for the inconvenience and we will try to update the documentation as soon as possible.

Regards,
Vasil
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Romel
Top achievements
Rank 1
answered on 11 May 2015, 02:58 AM

Thanks Vasil, for the reply please next time let us know if theres an updates like push an email or notification from your site. We encountered a problem on the day that we need to demo the app because of this we failed to demo it to our superiors and clients. 

 

Regards,

Romel

0
Rupesh
Top achievements
Rank 1
answered on 23 Apr 2016, 11:27 AM

Hello,

I want to get the list of users registered in the backend services. I am able to get that using  everlive.Users.get() but I want to get it using kendo.data.DataSource. I want to get this list using kendo datasource because I need to filter the users list on certain situations. That will be much easier if I get all users in kendo datasource.

Please let me know how can I achieve that?

Thank  you,

Rupesh

0
Anton Dobrev
Telerik team
answered on 26 Apr 2016, 09:05 AM
Hello Rupesh,

Thanks for your question. To filter the user accounts on certain conditions you can use the everlive.users.get method in a combination with a filter using the same querying API as with other data types. More information is available here

In a similar way you can use the Kendo UI data source dialect with a filter expression as shown here.

Let me know if this works for you.

Regards,
Anton Dobrev
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Rupesh
Top achievements
Rank 1
answered on 05 Jul 2016, 12:36 PM

Hello Anton, 
Thanks for your reply. It was really helpful.

I would like to ask one more question. Is there a way to group data together by some field and then get latest one for every grouping?

for example, I have a table (Type) in backend which contains 'CreatedDate' and 'CreatedBy' fields. Suppose if I have multiple entries for created by with different dates, I want to get only latest entry for every user (CreatedBy).

So I have data something like attachement 1(capture.png), and want to filter it like attachement 2(capture2.png)

 

Please let me know how can I achieve that?

Thank you,

Rupesh

0
Tsvetomir Nedyalkov
Telerik team
answered on 07 Jul 2016, 02:19 PM
Hello Rupesh,

  The easiest way to achieve this on the client side is by using the Kendo datasource group.aggregates option, specifying in the datasource initialization the following:

group: {
    field: "CreatedBy",
    aggregates: [
      { field: "CreatedAt", aggregate: "max" }
    ]
}


Please, have in mind that 'CreatedAt' field values should be valid Date objects. You can convert the values of the CreatedAt field returned by the server to a JS Date object using the parse configuration of the data source.

You can also use the server Aggregation and Grouping with the JavaScript SDK methods as explained here. After the aggregated data is fetched, you can construct a data source instance from the result.

Let me know if this works for you.


Regards,
Tsvetomir Nedyalkov
Telerik by Progress
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Rupesh
Top achievements
Rank 1
answered on 09 Jul 2016, 07:44 AM

Hello Tsvetomir,
Thanks for your reply. The Kendo datasource group.aggregates approach that you suggested is really helpful. Now I have data grouped together in kendo DataSource. But it has all data in it.

Actually I am working on a mobile app which is using telerik backend services with kendo datasource MVVM. I want to bind the listview in a screen which will populate only latest records created by each user('createdBy' field). So I thought that I can achieve it by grouping the data on 'CreatedBy' and picking up max 'CreatedDate' for each group. After using the group.aggregates,I am still getting all records in datasource. I want to get only latest records in the datasource.

 

Thank you,

Rupesh

0
Anton Dobrev
Telerik team
answered on 13 Jul 2016, 09:21 AM
Hello,

@Rupesh

I am assuming that you have a content type which data you would like to fetch and display grouped by a respective user (the CreatedBy field) and display the latest items (say it N) items for each group. Is this correct?

The reason you are getting all items is because the grouping and aggregation is done on the client (in the mobile app) and prior to this all items are fetched from the server. 

I am afraid that you cannot instruct out of the box neither the data source nor the server to return a subset of the items for each group.

Can you please specify how this data is going to be presented - there may be a few approaches when the data is shown in groups first and then for each user a details view fetches the latest comments, or for example, display only the users that have posts for a given time-frame and subsequently in a details page show their latest posts. This said, can you elaborate more how your data is organized, retrieved and displayed so that we can equip you with more information how to make the most out of the tools and services in Telerik Platform?

Regards,
Anton Dobrev
Telerik by Progress
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
HansenHouse
Top achievements
Rank 1
answered on 13 Jul 2016, 11:52 AM

Hello Anton, 

 

Thank you for the valuable reply. Actually I have made slight change in the functionality of an app.In the app the users were able to make more than one entries earlier but Now I have restricted them to make only one entry at a time for single request. So I don't need to get data in the grouped format any more. I appreciate your quick reply as it contributed more in my understanding towards telerik backend services.

 

I would like to ask one more question. 

I have two tables(types) in backend service. 'Requests' and 'Offers', each request can have multiple offers.The Offers table contains the request id field and 'Is_Accepted' flag (true/false).

I have kenod datasource configured for Requests type. Can I filter the datasource in such a way that It should return me only those requests that have offers where 'Is_Accepted' = false?

Can we perform SQL kind of joins in kendo datasource where we can access data from multiple types?

 

Thanks,

Rupesh

0
Martin
Telerik team
answered on 15 Jul 2016, 11:52 AM

Hi Rupesh,

My name is Martin, filling if for my colleague Anton.

When using expand expression there are a couple of limitations that need to be taken into account:

  • Filtering and sorting - in your case when you query the "Request" content type and you expand the "Offers" content type, you cannot filter the "Request" results based on values in "Offers" content type - you may filter the results return from the "Offers" content type only and only.
  • Maximum result item count - each request result is limited to 50 items when using expand expressions.

In general a NoSQL database is quite different from a relational database mainly in these cases:

  • in a NoSQL database data de-normalization is preferred (in relational it is the opposite) - The de-normalization allows you to go with the strategy of storing (embedding) large amounts of related data in a single rich document. This alleviates you of the chore of creating many content types with relations between them. You may still create relations, although they only makes sense when imposed by the client app's data access patterns and their frequency or when you need to set up specific permissions for a given content type or content type items.
  • Optimize your schema for the most frequent use cases - use only one Content Type instead of two - this will create duplicate data but will lead to faster queries.

This said, you may consider:

  • Querying the "Offers" so that you can filter the results by 'Is_Accepted' = false and expand the "Requests" content type to view all related items there.
  • To use only one Content Type instead of two ("Request" and "Offers") in case you do not have different access restrictions on the two. ​Thus you will reduce the usage of relations and will not have to comply with the limitation they introduce.
Let me know if this has helped.

Regards,
Martin
Telerik by Progress
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
HansenHouse
Top achievements
Rank 1
answered on 23 Jul 2016, 06:38 AM

Hi Martin,
Thanks for your reply. It is really helpful. I have now changed my schema and using a single content type as you suggested. I am now able to access all the required data in single object. 
But I am getting some difficulties in filtering on the relational fields. So for example, I am now getting Request and offers data in single object and the data for 'Request' type is like this,

[{
    "Offers":[{    
        "deadline":"2016-07-21T06:20:23.138Z",
        "amount":"25",
        "CreatedAt":"2016-07-20T12:06:43.684Z",
        "ModifiedAt":"2016-07-20T12:06:43.684Z",
        "CreatedBy":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ModifiedBy":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "Id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    }],
    "active":true,
    "status":"Open",
    "CreatedAt":"2016-07-19T06:20:58.498Z",
    "ModifiedAt":"2016-07-21T10:23:49.373Z",
    "CreatedBy":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ModifiedBy":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "hasOffers":true,
    "Id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}]

I am trying to filter this data based on Offers.CreatedBy, Basically it should return me only those 'Requests' that has offers CreatedBy the user. 

Is it possible using kendo datasource?  I have tried normal approach

dataSource.filter({ field: 'Offers.CreatedBy', operator: 'eq', value: localStorage.getItem('userId') });

but it is not working for the array fields or relational fields.

Please help me.

 

Thanks,

Rupesh

0
George
Telerik team
answered on 27 Jul 2016, 09:08 AM
Hello Zack,

Thank you for writing.

In your case you need to use a specific database operator to filter the data as shown in this example:
{
    "Offers": {
        "$elemMatch": {
            "CreatedBy": "xxxxxx"
        }
    }
}

This is an X-Everlive-Filter header that you need to supply with your request. More about the use of MongoDB queries you can find in our documentation here: http://docs.telerik.com/platform/backend-services/rest/queries/queries-mongodb-operators.


In case of using the Kendo UI Data Source component you can set the filter in the read.headers config option (and do not use the filter configuration for the above query):
var myFilter = .....// see above
 
{
            type: "everlive",
            transport: {
                typeName: "Offers",
                read: {
                    headers: {
                        "X-Everlive-Filter": JSON.stringify(myFilter)
                    }
                }
            },
      ....

In case of using the SDK methods you can set the filter to the get method.

I hope this will help.

Regards,
George
Telerik by Progress
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
HansenHouse
Top achievements
Rank 1
answered on 29 Jul 2016, 04:01 PM

Hello George,

Thank you for reply. I tested the way you mentioned. But I found that the mongodb operators are seems to be working only if we have that array field into the same content type. But in my case, data that I mentioned in the previous post is coming after expanding the type. I mean after X-Everlive-Expand. 

So the Mongodb operators are not working on this. To make sure of that I tested it without expanding the offers and it worked fine. 

Is there any way which can allow me to use these mongodb operators on final data?

Or is it possible to expand 'offers' first and then force mongodb operators to apply?

Please suggest me right solution. 

 

Thanks,

Rupesh

0
George
Telerik team
answered on 02 Aug 2016, 12:34 PM
Hello Rupesh,

Thank you for your reply.

I see in your previous post that you said your data consists of a single data type now, which means that the data type Requests holds the Offers field as a nested array, instead of another data type. Is that correct? If this is so, then my approach should work.

However, keep in mind that you cannot achieve the desired results using expand expressions due to their limitations. This functionality (filtering on the expanded data) can be done only when you are fetching an item per Id and expanding its related items as explained here.

This is why, just as Martin suggested, I would suggest to you to change your data model.

Let me know, should you require further assistance.

Regards,
George
Telerik by Progress
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
Tags
General Discussion
Asked by
Kelly
Top achievements
Rank 1
Answers by
Anton Dobrev
Telerik team
Emmanuel
Top achievements
Rank 1
Daniel Plomp
Top achievements
Rank 2
Romel
Top achievements
Rank 1
Vasil
Telerik team
Rupesh
Top achievements
Rank 1
Tsvetomir Nedyalkov
Telerik team
HansenHouse
Top achievements
Rank 1
Martin
Telerik team
George
Telerik team
Share this question
or