locked
SharePoint REST API with Javascript RRS feed

  • Question

  • Hey I am using rest services with javascript in SharePoint 2013 App, but I am getting error in url.

    Url works perfectly in browser and it retrieves data in XML format, but from app it is firing error.

    My Javascript code is as follows:

    var context;
    var web;
    var user;

    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady);

    function sharePointReady() {
      context = new SP.ClientContext.get_current();
      web = context.get_web();
      getUserName();
    }

    function getUserName() {
        user = web.get_currentUser();
        context.load(user);
        context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
    }

    // This function is executed if the above OM call is successful
    // It replaces the content of the 'welcome' element with the user name
    function onGetUserNameSuccess() {
        $('#message').text('Hello ' + user.get_title());
    }

    // This function is executed if the above OM call fails
    function onGetUserNameFail(sender, args) {
        alert('Failed to get user name. Error:' + args.get_message());
    }

    $(document).ready(function()
    {
     
      // parse together URL for HTTP GET request
      var requestUri = "https://appnapa.sharepoint.com/_api/Web/?$select=Title";

      // transmit GET request to SharePoint host environment
      var jqhxr = $.getJSON(requestUri, null, onSuccess);
      jqhxr.error(onFail);
    });

    function onSuccess(data) {
      var appWebTitle = data.d.Title;
      $("#messages").text(appWebTitle);
    }

    function onFail(errorObject, errorMessage) {
      $("#messages").text("Error: " + errorMessage);
    }

    It displays Error:error

    Can anybody help me with it? I am facing this problem with any rest api.

    Wednesday, January 30, 2013 8:56 AM

Answers

  • Hi,

    _spPageContextInfo.webAbsoluteUrl will get you the URL of your app web.  Do you want that title or do you want to get the title (and other data) from the Host web?  If you want the host web url, you will have to use something like this:

    var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
    
    function getQueryStringParameter(paramToRetrieve) {
        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] == paramToRetrieve)
                return singleParam[1];
        }
    }

    There is also an issue of going across domains from the App Web domain to the Host Web domain.  There is good background for this in this MSDN article: http://msdn.microsoft.com/en-us/library/fp179927.aspx.

    In order to get REST data from the host web, you will need to specify a different request URL.  The format is like this:

    var requestUri = appweburl +
                "/_api/SP.AppContextSite(@target)/web/?@target='" +
                    hostweburl + "'&$select=Title";
    

    And even then, you are not quite done if you want to get JSON data instead of XML.  The $.getJSON method does not pass the right request headers for that.  The following will send the propert request headers:

     $.ajax({
            url: requestUri,
            type: 'GET',
            dataType: 'json',
            success: onSuccess,
            error: onFail,
            beforeSend: setHeader
        });
    
    function setHeader(xhr) {
        xhr.setRequestHeader("Accept", "application/json; odata=verbose");
    }

    So if you put it all together, this is what I came up with which worked in my test app:

    var context;
    var web;
    var user;
    var hostweburl;
    var appweburl;
    
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady);
    
    function sharePointReady() {
        context = new SP.ClientContext.get_current();
        web = context.get_web();
        getUserName();
    }
    
    function getUserName() {
        user = web.get_currentUser();
        context.load(user);
        context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
    }
    
    // This function is executed if the above OM call is successful
    // It replaces the content of the 'welcome' element with the user name
    function onGetUserNameSuccess() {
        $('#message').text('Hello ' + user.get_title());
    }
    
    // This function is executed if the above OM call fails
    function onGetUserNameFail(sender, args) {
        alert('Failed to get user name. Error:' + args.get_message());
    }
    
    $(document).ready(function () {
    
        // parse together URL for HTTP GET request
        //var requestUri = "https://appnapa.sharepoint.com/_api/Web/?$select=Title";
    
        // transmit GET request to SharePoint host environment
        //var jqhxr = $.getJSON(requestUri, null, onSuccess);
        //jqhxr.error(onFail);
    
        //Get the Host Web URL as a URI decoded URL.
        hostweburl =
            decodeURIComponent(
                getQueryStringParameter("SPHostUrl")
        );
    
        appweburl = _spPageContextInfo.webAbsoluteUrl
    
        // To get the title of the host web
        var requestUri = appweburl +
                "/_api/SP.AppContextSite(@target)/web/?@target='" +
                    hostweburl + "'&$select=Title";
    
        // To get the title of the current App web
        //var requestUri = appweburl + '/_api/web/title';
    
        $.ajax({
            url: requestUri,
            type: 'GET',
            dataType: 'json',
            success: onSuccess,
            error: onFail,
            beforeSend: setHeader
        });
    });
    
    function onSuccess(data) {
        var appWebTitle = data.d.Title;
        $("#messages").text(appWebTitle);
    }
    
    function onFail(errorObject, errorMessage) {
        $("#messages").text("Error: " + errorMessage + " - Status: " + errorObject.status.toString() + ", " + errorObject.statusText);
    }
    
    function getQueryStringParameter(paramToRetrieve) {
        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] == paramToRetrieve)
                return singleParam[1];
        }
    }
    
    function setHeader(xhr) {
        xhr.setRequestHeader("Accept", "application/json; odata=verbose");
    }
    

    Regards

    -mfharvey

    • Proposed as answer by Steve.Curran Wednesday, January 30, 2013 10:10 PM
    • Marked as answer by Synoverge Thursday, January 31, 2013 8:37 AM
    • Unmarked as answer by Synoverge Thursday, January 31, 2013 9:52 AM
    • Marked as answer by Synoverge Friday, February 1, 2013 7:37 AM
    Wednesday, January 30, 2013 10:05 PM
  • Hey I solved my problem by giving permissions from app properties of napa tool.

    Thanks a lot for help :)

    • Marked as answer by Synoverge Friday, February 1, 2013 7:37 AM
    Friday, February 1, 2013 7:37 AM

All replies

  • Please try using:

    var requestUri = _spPageContenxtInfo.webAbsoluteUrl + "/_api/web/?$select=Title";


    Blog | SharePoint Field Notes Dev Tool | ClassMaster

    Wednesday, January 30, 2013 4:25 PM
  • Hi,

    _spPageContextInfo.webAbsoluteUrl will get you the URL of your app web.  Do you want that title or do you want to get the title (and other data) from the Host web?  If you want the host web url, you will have to use something like this:

    var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
    
    function getQueryStringParameter(paramToRetrieve) {
        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] == paramToRetrieve)
                return singleParam[1];
        }
    }

    There is also an issue of going across domains from the App Web domain to the Host Web domain.  There is good background for this in this MSDN article: http://msdn.microsoft.com/en-us/library/fp179927.aspx.

    In order to get REST data from the host web, you will need to specify a different request URL.  The format is like this:

    var requestUri = appweburl +
                "/_api/SP.AppContextSite(@target)/web/?@target='" +
                    hostweburl + "'&$select=Title";
    

    And even then, you are not quite done if you want to get JSON data instead of XML.  The $.getJSON method does not pass the right request headers for that.  The following will send the propert request headers:

     $.ajax({
            url: requestUri,
            type: 'GET',
            dataType: 'json',
            success: onSuccess,
            error: onFail,
            beforeSend: setHeader
        });
    
    function setHeader(xhr) {
        xhr.setRequestHeader("Accept", "application/json; odata=verbose");
    }

    So if you put it all together, this is what I came up with which worked in my test app:

    var context;
    var web;
    var user;
    var hostweburl;
    var appweburl;
    
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady);
    
    function sharePointReady() {
        context = new SP.ClientContext.get_current();
        web = context.get_web();
        getUserName();
    }
    
    function getUserName() {
        user = web.get_currentUser();
        context.load(user);
        context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
    }
    
    // This function is executed if the above OM call is successful
    // It replaces the content of the 'welcome' element with the user name
    function onGetUserNameSuccess() {
        $('#message').text('Hello ' + user.get_title());
    }
    
    // This function is executed if the above OM call fails
    function onGetUserNameFail(sender, args) {
        alert('Failed to get user name. Error:' + args.get_message());
    }
    
    $(document).ready(function () {
    
        // parse together URL for HTTP GET request
        //var requestUri = "https://appnapa.sharepoint.com/_api/Web/?$select=Title";
    
        // transmit GET request to SharePoint host environment
        //var jqhxr = $.getJSON(requestUri, null, onSuccess);
        //jqhxr.error(onFail);
    
        //Get the Host Web URL as a URI decoded URL.
        hostweburl =
            decodeURIComponent(
                getQueryStringParameter("SPHostUrl")
        );
    
        appweburl = _spPageContextInfo.webAbsoluteUrl
    
        // To get the title of the host web
        var requestUri = appweburl +
                "/_api/SP.AppContextSite(@target)/web/?@target='" +
                    hostweburl + "'&$select=Title";
    
        // To get the title of the current App web
        //var requestUri = appweburl + '/_api/web/title';
    
        $.ajax({
            url: requestUri,
            type: 'GET',
            dataType: 'json',
            success: onSuccess,
            error: onFail,
            beforeSend: setHeader
        });
    });
    
    function onSuccess(data) {
        var appWebTitle = data.d.Title;
        $("#messages").text(appWebTitle);
    }
    
    function onFail(errorObject, errorMessage) {
        $("#messages").text("Error: " + errorMessage + " - Status: " + errorObject.status.toString() + ", " + errorObject.statusText);
    }
    
    function getQueryStringParameter(paramToRetrieve) {
        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] == paramToRetrieve)
                return singleParam[1];
        }
    }
    
    function setHeader(xhr) {
        xhr.setRequestHeader("Accept", "application/json; odata=verbose");
    }
    

    Regards

    -mfharvey

    • Proposed as answer by Steve.Curran Wednesday, January 30, 2013 10:10 PM
    • Marked as answer by Synoverge Thursday, January 31, 2013 8:37 AM
    • Unmarked as answer by Synoverge Thursday, January 31, 2013 9:52 AM
    • Marked as answer by Synoverge Friday, February 1, 2013 7:37 AM
    Wednesday, January 30, 2013 10:05 PM
  • Thanks Steve, i tried that but its not working. 
    Thursday, January 31, 2013 8:33 AM
  • Thanks a lot.

    But I am getting error.

    It shows:

    Error: parsererror - Status: 200, parsererror

    Can you please help me with it?


    Thursday, January 31, 2013 8:37 AM
  • Hi,

    I'm suddenly having trouble deploying my app to my preview site so I can't test this theory, but according to a Google search I just ran, the "parsererror" can occur with the jquery library verson 1.6.2.  If you are developing your app with the Napa tool, then 1.6.2 is the default jQuery library version that is used.  But if you create a new app in Visual Studio 2012, it uses version 1.7.1.

    What version are you using?  If it is not 1.7.1, then change your jquery reference to try that instead and let me know if that helps.

    regards,

    -mfharvey

    Thursday, January 31, 2013 2:19 PM
  • Hi mfharvey,

    I am developing in napa tool & it was having 1.6.2 jquery, I did as u said but still error remains the same.

    It shows: parsererror - Status: 200, OK

    I am unable to use any REST API in Napa Tool, Please help me out.

    Thanks a lot!!

    Friday, February 1, 2013 5:19 AM
  • Hey I solved my problem by giving permissions from app properties of napa tool.

    Thanks a lot for help :)

    • Marked as answer by Synoverge Friday, February 1, 2013 7:37 AM
    Friday, February 1, 2013 7:37 AM
  • You can use angular js and SharePoint rest api:

    Here's a blog which details step by step instruction in linking angular js with SharePoint Rest API.

    https://bizloadsolutions.com/2017/03/16/sharepoint-angular-and-bootstrap-form-part-1/

    Also if you want to know the properties of _spPageContextInfo for SharePoint online 365, you can look at this article as well:

    https://bizloadsolutions.com/2017/03/22/sharepoint-online-365-_sppagecontextinfo/

    <script type="text/javascript">
    
            var app = angular.module("myApp", []);
            app.controller("myCtrl", function($scope, $location) {
    
                var userid = _spPageContextInfo.userId;
                var requestUriGetUserDetails = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + userid + ")";
                $scope.contentTypeTemplate = "application/json;odata=verbose";
                $scope.requestHeadersTemplate = { "accept" : "application/json;odata=verbose" };
    
                $.ajax({
                    url : requestUriGetUserDetails,
                    contentType : $scope.contentTypeTemplate,
                    headers : $scope.requestHeadersTemplate,
                    success : onSuccessGetUserDetails,
                    error : onErrorGetUserDetails
                });
    
                function onSuccessGetUserDetails(data, request){
                    var varFullName = data.d.Title;
                    var varEmail = data.d.Email;
                    var varLoginName = data.d.LoginName;
    
                    $scope.loginName = varLoginName;
                    $scope.email = varEmail;
                    $scope.requestorEmail = varEmail;
                    $scope.requestorFullName = varFullName;
    
                    var fullNameArray = varFullName.split(" ");
    
                    var firstNameValue = fullNameArray[0];
                    var lastNameValue = fullNameArray[1];
    
                    $scope.firstName = firstNameValue;
                    $scope.lastName = lastNameValue;
    
                    $scope.$apply();
                }
    
                function onErrorGetUserDetails(error) {
                    alert(error);
                }
    
            });
    
        </script>


    • Edited by Tazaroo007 Thursday, March 30, 2017 5:05 AM
    Thursday, March 30, 2017 5:03 AM