The Latest Time Saving Tips for Your SharePoint Deployment

Corey Roth

Subscribe to Corey Roth: eMailAlertsEmail Alerts
Get Corey Roth: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Intel XML, XML Magazine, SharePoint Archiving Journal

Blog Feed Post

How to: Query SharePoint 2013 using REST and JavaScript

I have a session coming up at SharePoint Summit Toronto this year about the many different ways you can query search.  Whenever I am working on a new talk, it is customary for me to write blog posts about my examples so here it is. :)  I first learned how to query SharePoint 2013 search with the new REST API and JavaScript from looking at examples from @ScotHillier on MSDN.  However, the last time I tried the example, I noticed an issue which I equate to most likely a change between beta and RTM.  This post shows you my version of how to query search using the REST API and JavaScript. 

For this post, I am using the RTM Office Developer tools (which I have a post coming out on soon).  I am going to use a SharePoint-hosted app for my example but you could also use this in a web part with farm solution as well.  When it comes to apps, you need to be sure and request permission to access search.  Do this by editing your AppManifest.xml and clicking on the permissions tab.  Select Search and then select QueryAsUserIgnoreAppPrincipal.  If you forget this step, you won’t get an error, your queries will simply just return zero results.

SearchAppRESTPermission

For my example, I am just going to add my code to the default.aspx page in the app.  I simply add a textbox, a button, and a div to hold the results.  The user will type in his or her query, click the button, and then see search results.  You could put this in a Client Web Part if you wanted. 

<div>

    <label for="searchTextBox">Search: </label>

    <input id="searchTextBox" type="text" />

    <input id="searchButton" type="button" value="Search" />

</div>

 

<div id="resultsDiv">

</div>

Now, we need to add the necessary code to App.js.  I start by removing the example code that retrieves the user information.  I instead, add a click handler to my searchButton to execute the search query.  If you remember from my previous post on REST, we assemble a URL by appending /api/search/query to a SharePoint host URL.  For example.

http://server/_api/search/query

However, in an app, we have to request the URL to the App.  One way to do this is by query string using the SPAppWebUrl parameter.  SharePoint passes this parameter to your app start page automatically.  We can request it with a line line this.  Remember getQueryStringParameter() is a helper method that we have gotten from some of the SharePoint examples.  I’ll include it in the full code listing at the bottom of this post.

var

spAppWebUrl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));

To pass the user’s query to SharePoint, we need to include the querytext parameter on the REST URL.  Be sure to enclose the value in single quotes.  Again more details in my previous post.

http://server/_api/search/query?querytext=’SharePoint’

Now, we need to create a click handler for the search button, build the URL, and then execute the query.

$(

"#searchButton").click(function () {

});

Inside the click handler, assemble the URL, using the concatenation of the spAppWebUrl, /api/search/query, and the querytext parameter.  The value of querytext will be retrieved from the textbox we added earlier.

var queryUrl = spAppWebUrl + "/_api/search/query?querytext='" + $("#searchTextBox").val() + "'";

Now, we just execute the query with $.ajax().  Pass the queryUrl in the url parameter.   This example uses the GET method but if you have a lot of parameters, you may consider using POST instead.  Lastly, this part is key to get this example to work.  The accept header must have value of "application/json; odata=verbose".  The odata=verbose part is not in the MSDN example.  If you leave it out, you will receive an error.  The last parameters are the methods that will handle the success and failure of the AJAX call.  Here’s what the whole method looks like.

$("#searchButton").click(function () {

    var queryUrl = spAppWebUrl + "/_api/search/query?querytext='" + $("#searchTextBox").val() + "'";

 

    $.ajax({ url: queryUrl, method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: onQuerySuccess, error: onQueryError });

});

Now, you need to write code to handle the success.  The results come back in JSON format, but unfortunately, they are buried in a hugely nested structure.  Each individual result can be found in data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results.  Your best bet is to assign this a variable and then use a template or manually parse it. In my example, I am just going to use $.each to iterate through the results using brute force.  The individual columns of each search result can be found in this.Cells.results.Value.  Ok, that’s confusing I am sure, so let’s look at the code and then step through it.  I’m just writing out a simple table by appending HTML tags to a div.

function onQuerySuccess(data) {

    var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

 

    $("#resultsDiv").append('<table>');

 

    $.each(results, function () {

        $("#resultsDiv").append('<tr>');

        $.each(this.Cells.results, function () {

            $("#resultsDiv").append('<td>' + this.Value + '</td>');

        });

        $("#resultsDiv").append('</tr>');

    });

 

    $("#resultsDiv").append('</table>');

}

Effectively, I have two nested loops.  One to iterate through each result and one for each managed property (column) in the results.  When you get inside the Cell, this.Value will show the value of the result while this.Key will contain the name of the managed property. 

The last thing to implement is the code to handle errors.  It’s relatively simple and just writes error.StatusText to the div.

function onQueryError(error) {

    $("#resultsDiv").append(error.statusText)

}

When I run my app, here is what it looks like.

SearchAppDefault

Executing a query in the app, gives us results but they aren’t pretty.  You can pretty them up yourself. :)  It also doesn’t include anything to print out the managed property names on the table.  You could get the names by looking at each cell of the first result and using this.Value.

SearchAppResults

You can see, it’s really pretty easy to get started.  You can further refine your REST query to request specific fields, sort orders, and more.  I’ll probably write a follow-up post in the future to include some of those details. Here’s the whole source code for my example that you can work with.

var context = SP.ClientContext.get_current();

 

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model

$(document).ready(function () {

 

    var spAppWebUrl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));

 

    $("#searchButton").click(function () {

        var queryUrl = spAppWebUrl + "/_api/search/query?querytext='" + $("#searchTextBox").val() + "'";

 

        $.ajax({ url: queryUrl, method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: onQuerySuccess, error: onQueryError });

    });

 

});

 

function onQuerySuccess(data) {

    var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

 

    $("#resultsDiv").append('<table>');

 

    $.each(results, function () {

        $("#resultsDiv").append('<tr>');

        $.each(this.Cells.results, function () {

            $("#resultsDiv").append('<td>' + this.Value + '</td>');

        });

        $("#resultsDiv").append('</tr>');

    });

 

    $("#resultsDiv").append('</table>');

}

 

function onQueryError(error) {

    $("#resultsDiv").append(error.statusText)

}

 

//function to get a parameter value by a specific key

function getQueryStringParameter(urlParameterKey) {

    var params = document.URL.split('?')[1].split('&');

    var strParams = '';

    for (var i = 0; i < params.length; i = i + 1) {

        var singleParam = params[i].split('=');

        if (singleParam[0] == urlParameterKey)

            return decodeURIComponent(singleParam[1]);

    }

}

That’s all there is to it.  Hopefully, you find this example useful.  Thanks.

Read the original blog entry...

More Stories By Corey Roth

Corey Roth, a SharePoint Server MVP, is a consultant at Hitachi Consulting specializing in SharePoint and Office 365 for clients in the energy sector. He has more than ten years of experience delivering solutions in the energy, travel, advertising and consumer electronics verticals.

Corey specializes in delivering ECM and search solutions to clients using SharePoint. Corey has always focused on rapid adoption of new Microsoft technologies including Visual Studio 2013, Office 365, and SharePoint.

He is a member of the .NET Mafia (www.dotnetmafia.com) where he blogs about the latest technology and SharePoint. He is dedicated to the community and speaks regularly at user groups and SharePoint Saturdays.