How to work with data in mobile services with Visual Studio (JavaScript backend)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

If you create a Azure mobile service that's associated with a Azure SQL database and then create data tables in that database, you can access the data in those tables from any device that can access your service. You can also customize the behavior of your service by editing the server scripts that run when you interact with your data tables. The scripts are associated with events on your mobile service's data tables. For example, you can send messages called push notifications from your mobile service to your client app when data changes.

If you're using the .NET backend, see How to use controllers to access data (.NET backend).

Prerequisites

  • Windows 8.1
  • Microsoft Visual Studio 2013

Instructions

Step 1: How to create a mobile service

You can create a mobile service by using Server Explorer in Visual Studio or by using the Azure management portal. See Get started with Mobile Services. To use Server Explorer, you must first import your Azure subscription (a .publishsettings file).

  1. If you've already imported a subscription, skip to the last step in this procedure.

  2. In Visual Studio, open Server Explorer, open the shortcut menu for the Mobile Services node, and then choose Import subscription.

  3. In the Import subscription dialog box, choose the Download subscription information link, and then specify your credentials for Azure.

    Your credentials for Azure might differ from those that you use for your Windows Store subscription.

  4. Save the .publishsettings file to a location on your local machine, choose the Browse button, and then open the folder where you saved the .publishsettings file.

    You can later add and remove subscriptions and the mobile services that are associated with them if you open the shortcut menu for the Azure Mobile Services node and then choose Manage subscriptions.

  5. In Server Explorer, open the shortcut menu for the Mobile Services node, and then choose Create Service.

    The Create Mobile Service dialog box appears.

  6. In the Subscription list, choose the subscription with which you want to associate the service that you're creating.

    If the subscription that you want doesn't appear in the list, import it by following the steps earlier in this procedure.

  7. Give the mobile service a name that's unique among all mobile services that have been created in Azure.

    If a red X icon appears, someone has already used the name that you chose, and you must choose a different name. Note the full name of the mobile service: YourMobileServiceName.azure-mobile.net.

  8. Choose the type of runtime for mobile service you want to create. There are two choices: JavaScript and .NET. The JavaScript runtime and the .NET runtime use different programming languages and different development environments. If you choose the JavaScript runtime, your service must be implemented using server-side Node.js scripts, which you can edit from Visual Studio Server Explorer. If you choose the .NET runtime, you implement your service in a C# or Visual Basic project in Visual Studio, and the project type is based on Web API, a type of ASP.NET service.

  9. (Optional) Choose a region for your mobile service. This corresponds to the location of the data center where your mobile service will be hosted. You should choose the region that's closest to where most of your customers are located. If you already have a database that you want to use and it is in a specific region, you should choose the same region since there is a lot of network communication between a mobile service and its database. You will incur extra charges for these communications if the database is in a different region.

  10. In the Database list, choose the database and server to use, or choose Create New to create a database, set up a server, or both.

  11. In the Server user name and Server password text boxes, specify the credentials that you use to access the database server that's associated with your subscription.

    Enter the credentials for the server, not for a specific database. If you're creating a database server, enter a new password. If a red X icon appears, you must choose a stronger password to meet complexity requirements.

  12. Choose the Create button to create the service.

    The service might take about 20 seconds to create.

Step 2: How to create a data table (JavaScript runtime)

By creating a database table, you can store data in that table that you can access from any device that can access the mobile service that's associated with the database. For example, your client app might store data for later retrieval, or a scheduled process could run on the server to periodically update data that then becomes available to your app. You can also store data you want to share between users of your application. You access data in the table by using the mobile services APIs. For more information about how to use data tables in mobile services, see Get started with data in mobile services.

  1. In Server Explorer, open the shortcut menu for the node that's associated with your mobile service, and then choose Create Table.

    The Create Table dialog box appears.

  2. Give the table a name.

  3. (Optional) Expand the Advanced area, and specify permissions for the table.

    You can add or edit permissions later.

    See Permissions.

  4. Choose the Create button to create the table.

  5. Insert data by using the InsertAsync method of the mobile services API.

    As you insert data, columns are automatically added for that data. Different data can have different columns.

Step 3: How to edit scripts for your data tables (JavaScript runtime)

You can customize your app's use of data by editing the JavaScript scripts that run when you interact with data tables. A script is associated with each major operation that you can perform on the data tables: read, update, insert, and delete. These scripts run on the server along with the database that's associated with your mobile service. See Validate and modify data in mobile services by using server scripts.

  1. In Server Explorer, expand the node for the mobile service that has the script that you want to edit.

  2. Open the shortcut menu on the script file, and then choose Edit Script.

    The script opens in an editor window. Notice that the scripts contain JavaScript functions, as the following script for read.js shows.

    function read(query, user, request) {
        request.execute();
    }
    

    This function runs whenever an HTTP request to read a data table comes in. The details of the request and the query and user credentials are available as parameters.

  3. Call request.execute if you want the operation to go through, or call request.response to deny the request and send to the user a response that includes an HTTP status code.

    You can review an example in the code for insert.js for the channels table, which your mobile service uses to manage channels for push notifications. In this code, a query is run on the tables object to determine whether a particular installationId is already entered. If the channel that's being inserted during registration for this installationId already exists and has the same URI, a response of HTTP 200 is issued along with the existing item as an entity.

    // See documentation at http://go.microsoft.com/fwlink/p/?LinkID=296704&clcid=0x409
    function insert(item, user, request) {
    
        // The following code manages channels and should be retained in this script
        var ct = tables.getTable("channels");
        ct.where({ installationId: item.installationId }).read({
            success: function (results) {
                if (results.length > 0) {
                    // we already have a record for this user/installation id - if the 
                    // channel is different, update it; otherwise, just respond
                    var existingItem = results[0];
                    if (existingItem.channelUri !== item.channelUri) {
                        existingItem.channelUri = item.channelUri;
                        ct.update(existingItem, {
                            success: function () {
                                request.respond(200, existingItem);
                            }
                        });
                    }
                    else {
                        // no change necessary; just respond
                        request.respond(200, existingItem);
                    }
                }
                else {
                    // no matching installation; insert the record
                    request.execute();
                }
            }
        })
    
    }
    

    Within the script, you have access to the scripting APIs for mobile services. See Azure Mobile Services Server Scripts and Mobile services server script reference.

    Tip A message appears if a server error occurs when you're working with a script for a mobile service, such as when you are trying to upload the modified code. In the message, you can choose the Retry link to run the operation again or the Details link to find out more about the error. As an alternative, you can retry the operation by choosing the Ctrl + Num * (the asterisk on the numeric keypad) keys and then choosing the Ctrl + R keys. You can also show details by choosing the Ctrl + Num * keys and then choosing the Ctrl + D keys.

    Tip See Enabling IntelliSense for server-side JavaScript.

Step 4: Debugging Mobile Service Scripts (JavaScript)

It's not possible to attach a debugger to an executing mobile service script, however, here are some debugging tips that will help you track down problems. These techniques can be used in any server-side mobile services script, such as the insert, delete, read, and update scripts for any table.

  1. Use the console object's log method to write to the mobile service's log file. See console object. Use the error method to record information about an error. The following example is taken from the insert script for a table called moves for a game that uses mobile services to send push notifications to other players who have installed the game. In this example, a function checks the channels table to find Uri for a channel based on its channelId, and then calls another function to send a push notification to that channel. The log traces execution through the code and writes the name of the table and the script in the log entry to help identify those entries.

    function getChannelUriAndSendNotification(request, user1Name, channelId, item) {
        // Query the channels table to find the right uri to push to
        var channelUri;
        console.log("Querying channels for channelId = " + channelId)
        var channels = tables.getTable("channels")
        channels.where({ id: channelId }).read({
            success: function (results) {
                if (results.length == 0) {
                    request.respond(500, "moves/insert.js: No channel found for channelId = " + channelId)
                    console.error("moves/insert.js: No channel found for channelId = " + channelId)
                    return;
                }
                if (results.length == 1) {
                    // Found a single channel
                    channelUri = results[0].channelUri;
                    sendPushNotificationToUser(request, user1Name, channelUri, item);
                } else {
                    // Error: more than channel found.
                    request.respond(500, "moves/insert.js: More than one channel found. NYI")
                    console.error("moves/insert.js: More than one channel found. NYI")
                    return;
                }
            }
        })
        console.log("getChannelUriAndSendNotification completing")//
    }
    

    To view the log file in Server Explorer, open the shortcut menu for the mobile service's node, and choose View Logs.

    To view the logs in the Azure Management Portal, open the LOGS tab for your mobile service.

    The most recent log entries appear first.

    Choose the Refresh link to download and view the latest data from the service.

  2. When failures occur in server-side scripts, the mobile service returns a HTTP 500 response code to the client. In .NET client code, this generates a MobileServiceInvalidOperationException, with a default message Internal Server Error. You can modify your scripts to report a more meaningful error message to the client. When error conditions occur, you can use the request.respond method to return a more detailed error message to the client. In the previous example, you can see how request.respond is used when an error occurs, such as not finding the desired channel.

    If an error isn't fatal to the operation (such as inserting an object into a table in the insert script), you should not call request.respond. The following example is part of the insert script for a table that tracks active games. In this example, a function in a mobile service script sends a badge push notification and a toast push notification. The functions sendBadge and sendToastText04 both have error handlers that write to the log, but request.respond isn't included here because failing to send a push notification should not prevent the insert from being performed.

    function sendPushNotificationToUser(request, user1Name, channelUri) {
    
        // Notify user2 that a new game has been started.
        push.wns.sendBadge(channelUri, "alert", {
            success: function (pushResponse) {
                console.log("games/insert.js: Sent badge push:", pushResponse);
            },
            error: function (err)
            { console.log("games/insert.js: Badge push failed for channel " + channelUri + " : " + err) }
        });
    
    
        push.wns.sendToastText04(channelUri, {
            text1: user1Name + " wants to play TicTacToe!"
        }, {
            success: function (pushResponse) {
                console.log("games/insert.js: Sent push:", pushResponse);
            },
            error: function(err)
            { console.log("games/insert.js: Push failed for channel " + channelUri + " : " + err)}
        });
    
        console.log("games/insert.js: sendPushNotificationToUser completing")
    }
    

Connecting to Azure Mobile Services

Overview: Code generated by push notification wizard

Quickstart: Working with mobile services in Visual Studio

Mobile Services server script reference