Welcome!

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.

Latest Stories
SYS-CON Events announced today that SourceForge has been named “Media Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. SourceForge is the largest, most trusted destination for Open Source Software development, collaboration, discovery and download on the web serving over 32 million viewers, 150 million downloads and over 460,000 active development projects each and every month.
There is a huge demand for responsive, real-time mobile and web experiences, but current architectural patterns do not easily accommodate applications that respond to events in real time. Common solutions using message queues or HTTP long-polling quickly lead to resiliency, scalability and development velocity challenges. In his session at 21st Cloud Expo, Ryland Degnan, a Senior Software Engineer on the Netflix Edge Platform team, will discuss how by leveraging a reactive stream-based protocol,...
Today most companies are adopting or evaluating container technology - Docker in particular - to speed up application deployment, drive down cost, ease management and make application delivery more flexible overall. As with most new architectures, this dream takes significant work to become a reality. Even when you do get your application componentized enough and packaged properly, there are still challenges for DevOps teams to making the shift to continuous delivery and achieving that reducti...
SYS-CON Events announced today that Daiya Industry will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Daiya Industry specializes in orthotic support systems and assistive devices with pneumatic artificial muscles in order to contribute to an extended healthy life expectancy. For more information, please visit https://www.daiyak...
SYS-CON Events announced today that Nihon Micron will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Nihon Micron Co., Ltd. strives for technological innovation to establish high-density, high-precision processing technology for providing printed circuit board and metal mount RFID tags used for communication devices. For more inf...
SYS-CON Events announced today that Massive Networks, that helps your business operate seamlessly with fast, reliable, and secure internet and network solutions, has been named "Exhibitor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. As a premier telecommunications provider, Massive Networks is headquartered out of Louisville, Colorado. With years of experience under their belt, their team of...
SYS-CON Events announced today that Suzuki Inc. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Suzuki Inc. is a semiconductor-related business, including sales of consuming parts, parts repair, and maintenance for semiconductor manufacturing machines, etc. It is also a health care business providing experimental research for...
"Our strategy is to focus on the hyperscale providers - AWS, Azure, and Google. Over the last year we saw that a lot of developers need to learn how to do their job in the cloud and we see this DevOps movement that we are catering to with our content," stated Alessandro Fasan, Head of Global Sales at Cloud Academy, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
Enterprises are moving to the cloud faster than most of us in security expected. CIOs are going from 0 to 100 in cloud adoption and leaving security teams in the dust. Once cloud is part of an enterprise stack, it’s unclear who has responsibility for the protection of applications, services, and data. When cloud breaches occur, whether active compromise or a publicly accessible database, the blame must fall on both service providers and users. In his session at 21st Cloud Expo, Ben Johnson, C...
21st International Cloud Expo, taking place October 31 - November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA, will feature technical sessions from a rock star conference faculty and the leading industry players in the world. Cloud computing is now being embraced by a majority of enterprises of all sizes. Yesterday's debate about public vs. private has transformed into the reality of hybrid cloud: a recent survey shows that 74% of enterprises have a hybrid cloud strategy. Me...
Many organizations adopt DevOps to reduce cycle times and deliver software faster; some take on DevOps to drive higher quality and better end-user experience; others look to DevOps for a clearer line-of-sight to customers to drive better business impacts. In truth, these three foundations go together. In this power panel at @DevOpsSummit 21st Cloud Expo, moderated by DevOps Conference Co-Chair Andi Mann, industry experts will discuss how leading organizations build application success from all...
SYS-CON Events announced today that mruby Forum will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. mruby is the lightweight implementation of the Ruby language. We introduce mruby and the mruby IoT framework that enhances development productivity. For more information, visit http://forum.mruby.org/.
Cloud-based disaster recovery is critical to any production environment and is a high priority for many enterprise organizations today. Nearly 40% of organizations have had to execute their BCDR plan due to a service disruption in the past two years. Zerto on IBM Cloud offer VMware and Microsoft customers simple, automated recovery of on-premise VMware and Microsoft workloads to IBM Cloud data centers.
Why Federal cloud? What is in Federal Clouds and integrations? This session will identify the process and the FedRAMP initiative. But is it sufficient? What is the remedy for keeping abreast of cutting-edge technology? In his session at 21st Cloud Expo, Rasananda Behera will examine the proposed solutions: Private or public or hybrid cloud Responsible governing bodies How can we accomplish?
Today traditional IT approaches leverage well-architected compute/networking domains to control what applications can access what data, and how. DevOps includes rapid application development/deployment leveraging concepts like containerization, third-party sourced applications and databases. Such applications need access to production data for its test and iteration cycles. Data Security? That sounds like a roadblock to DevOps vs. protecting the crown jewels to those in IT.