Progress will discontinue Telerik Platform on May 10th, 2018. Learn more

Expand Expression Examples

In this article you will find examples for expand expressions that cover the full gamut of expanding options. All examples are based on the Friends sample app data structure.

The content in this article is organized as follows:

Basic Relation Expansion

The most simple expand expression only specifies an expand field. As explained in Expand Expression Format, the expand expression format depends on where the relation is held:

The examples in this article use the data.expand() approach, which is one of two available options. The alternative Everlive.Query() approach is required in some situations such as when sorting or paging data before expanding it. See Defining a Relation Expanding Expression for more information.

The Queried Content Type Holds the Relation

When you are querying the content type that holds the relation field you need to specify that field in your expand expression and to include the related content type name using TargetTypeName.

The following example returns all Activities but replaces the Likes field that normally stores User IDs with the respective user object(s) from the related Users content type.

var everliveApp = new Everlive('your-app-id');

var expandExp = {
  "Likes" : {
    "TargetTypeName" : "Users"
    }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).get()
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

The request returns this result (using the Telerik Platform Friends social sample app). Some lines are skipped for brevity:

{
    "Count": 2,
    "Result": [{
        "Likes": [{
            "Username": "seth",
            "DisplayName": "Seth Peterson",
            ....
        }],
        "Text": "It is finally time for graduation! Good job everyone, we made it."
            ....
    }, {
        "Likes": [],
        "Text": "The most amazing sunset I have ever seen at Phuket, Thailand",
        ...
    }]
}

The Queried Content Type Does Not Hold the Relation

When the relation field is held in the related content type, you need to use a different expand expression format that specifies them.

For example, if you want to retrieve the Activities that have been liked by a given user, you can make a request to the Users content type, specifying that the Activities' Likes field relates the two content types:

var everliveApp = new Everlive('your-app-id');

var expandExp = {
  "Activities.Likes": true
};

var data = everliveApp.data('Users');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

The result is a single User object with a property Activities.Likes that contains an array of all Activities that have the user's ID in their Likes fields:

{
    "Result": {
        "Username": "seth",
        ...
        "Activities.Likes": [{
            "Text": "It is finally time for graduation! Good job everyone, we made it.",
            ...
        }]
    }
}

Renaming the Expanded Field

When expanding fields, the default behavior is to use the content type field name for the expanded field in the result. To rename the return field, pass the ReturnAs expand expression option. You can use it regardless of what side of the relation you are querying.

To preserve the integrity of your data, avoid returning a renamed field to the server, because this will add the new field to the database with the nested object inside.

The following example renames the return field from "Likes" to "UsersWhoLikeThisActivity":

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName" : "Users",
      "ReturnAs" : "UsersWhoLikeThisActivity"
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).get()
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

The result will look like this:

{
    "Result": [{
      "UsersWhoLikeThisActivity": [{
          "Username": "seth",
          "DisplayName": "Seth Peterson",
          ....
      }],
      "Text": "It is finally time for graduation! Good job everyone, we made it."
          ....
    }, {
      "UsersWhoLikeThisActivity": [],
      "Text": "The most amazing sunset I have ever seen at Phuket, Thailand",
      ...
    }],
    "Count": 2
}

Filtering

When expanding one-to-many relations, you can include an optional filtering expression to narrow down on the expanded data.

Filtering the result of the expand expression is possible only when reading by ID in the base query.

Filtering can be used regardless of whether you are querying the content type that holds the relation or not.

For example, the following expand expression filters the expanded data by the Email field.

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName" : "Users",
      "ReturnAs": "UsersWhoLikeThisActivity",
      "Filter": { "Email": { "$regex": "@telerik.com$" } }
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

Telerik Platform executes the following request (in a addition to the "by ID" request) behind the scenes, which returns all users with an email in the "telerik.com" domain who liked our activity.

var everliveApp = new Everlive('your-app-id');

var filter = { "$and": [
   {"Email": { "$regex": "@telerik.com$"} },
   { "Id": { "$in" : [ "user1Id", "user2Id" ] } }
]};

everliveApp.Users.get(filter)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

Sorting

Similar to filtering, a standard Telerik Platform sorting expression can be added to the expand expression. It sorts the array of expanded data in case of one-to-many relations. In case of one-to-one relations, the sorting expression is ignored.

Sorting is applied only for "by ID" requests. "By filter" request that return a single item are not considered a "by ID" case.

Sorting can be used regardless of whether you are querying the content type that holds the relation or not.

The following example request returns the activity with the specified ID together with all users who liked it sorted by their Email field in ascending order.

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName" : "Users",
      "ReturnAs": "UsersWhoLikeThisActivity",
      "Sort": { "Email" : 1 }
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

Paging

When you are dealing with a great amount of result data you can use paging to ensure that the service returns the requested items in a timely fashion and that the response will not consume an excessive amount of bandwidth. Paging is implemented using the Skip and Take options.

Because the result order could be different on each request, it is strongly recommended to use sorting along with paging.

The following example request returns only items 11 through 20.

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName" : "Users",
      "ReturnAs": "UsersWhoLikeThisActivity",
      "Skip": 10,
      "Take": 10
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

Selecting Return Fields

A fields expression is used to project the result (take only a subset of fields). It must be a valid Telerik Platform fields expression.

Fields selection can be used regardless of whether you are querying the content type that holds the relation or not.

Fields and SingleField cannot be used simultaneously.

The following example selects DisplayName and Email for returning and explicitly excludes Id which is otherwise always returned.

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName" : "Users",
      "ReturnAs": "UsersWhoLikeThisActivity",
      "Fields": {
         "DisplayName": 1, "Email": 1, "Id": 0
      }
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

And the result:

{
    "Id": "activityId",
    "UsersWhoLikeThisActivity": [{
        "DisplayName": "Andy Gerald",
        "Email": "andy.gerald@telerik.com"
    }, {
        "DisplayName": "Michael Taylor",
        "Email": "michael.taylor@telerik.com"
    }]
}

Returning a Single Field

There are cases where you are interested in just a single field of an expanded object such as the DisplayName field of a user object. The SingleField expand expression option allows you to completely replace the expanded object with that field's value.

Fields and SingleField cannot be used simultaneously.

The following example reads an activity by ID and adds all users who liked the activity, but instead of returning the entire user object, it replaces it with the value of the DisplayName field:

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Likes": {
      "TargetTypeName": "Users",
      "ReturnAs": "UsersWhoLikeThisActivity",
      "SingleField": "DisplayName"
   }
};

var data = everliveApp.data('Activities');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

And the result:

{
    "Id": "activityId-here",
    "Text": "It is finally time for graduation! Good job everyone, we made it.",
    "UsersWhoLikeThisActivity": [
        "Andy Gerald",
        "Michael Taylor"
    ]
}

Expanding File Metadata

Another example is expanding file metadata. Assume that you have a Books content type that stores a book collection. Each book has a field Cover of type File defined in the content type's structure that stores the Id of the book's cover image. If you want to retrieve the Uri where the image file is stored instead of retrieving its full metadata, you can do so by using SingleField like this:

var everliveApp = new Everlive('your-app-id');

var expandExp = {
   "Cover":{
      "TargetTypeName" : "System.Files",
      "ReturnAs":"CoverURL",
      "SingleField":"Uri"
   }
};

var data = everliveApp.data('Books');
data.expand(expandExp).getById(item-id)
    .then(function(data){
        console.log(JSON.stringify(data));
    },
    function(error){
        console.log(JSON.stringify(error));
    });

This request results in:

{
    "CoverURL": "https://bs1.cdn.telerik.com/v1/SLTCCCkPnud4GC29/0000bte0-c286-12e4-b57c-2939r6e80316",
    "CreatedAt": "2015-03-04T15:50:13.346Z",
    "ModifiedAt": "2015-03-04T15:50:13.346Z",
    "CreatedBy": "00000000-0000-0000-0000-000000000000",
    "ModifiedBy": "00000000-0000-0000-0000-000000000000",
    "Owner": "00000000-0000-0000-0000-000000000000",
    "Id": "0000f420-f286-11e4-9c5d-c5653ab2b427",
    "Meta": {
        "Permissions": {
        "CanRead": true,
        "CanUpdate": true,
        "CanDelete": true
        }
    }
}

See Also

To learn how to define an expand expressions, see Defining an Expand Expression.

Start a free trial Request a demo
Contact us: +1-888-365-2779
sales@telerik.com
Copyright © 2016-2017, Progress Software Corporation and/or its subsidiaries or affiliates. All rights reserved.