SPServices in SharePoint Hosted App?

Apr 17, 2013 at 7:13 AM
Has anyone managed to get the SPServices library to run inside an app page.

I have tried getlistitems and found no results returned.

I can achieve results with javascript CSOM within the app.
Coordinator
Apr 18, 2013 at 5:28 AM
Can you show what you've tried?

M.
Apr 18, 2013 at 10:38 AM
I have tried 3 scenarios (and combinations). I can get jquery/SPServices recognised, but I can't get a query on lists to work (refer to last code quoted at bottom of this post).

I can get simple jquery call to work and simple SPServices call:
<script ...>
alert ("js on.");
$(document).ready(function() {
    alert ('jQuery on.');
    var thisSite = $().SPServices.SPGetCurrentSite();
    alert ('Hello World! Your site is : ' + thisSite );
});

I put a simple script into a Napa page that uses context and can get the real site collection path:
<script ...>
    var context;
    var web;
    var spHostUrl;
    var parentContext;

    $(document).ready(function () {
        var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
        context = new SP.ClientContext.get_current();
        parentContext = new SP.AppContextSite(context, spHostUrl);
        web = parentContext.get_web();

        alert(spHostUrl);
    });

    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]);
        }
    }

I cannot get a call to an existing SP list to work, yet the same code works if inserted in a web page as Script web part!
<asp:Content ID="Content3" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<div>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/0.7.2/jquery.SPServices-0.7.2.min.js"></script>
    <script language="javascript" type="text/javascript">
        var context;
        var web;
        var spHostUrl;
        var parentContext;

        $(document).ready(function () {
            var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
            context = new SP.ClientContext.get_current();
            parentContext = new SP.AppContextSite(context, spHostUrl);
            web = parentContext.get_web();

            $().SPServices({
                operation: "GetListItems",
                async: false,
                weburl: spHostUrl + '/lcm',
                listName: "Brisbane Inbox",
                CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='Debtor_x0020_Code' /><FieldRef Name='Patient_x0020_Exit_x0020_Date' /></ViewFields>",
                completefunc: function (xData, Status) {
                  $(xData.responseXML).SPFilterNode("z:row").each(function() {
                    var liHtml = "<li>" + $(this).attr("ows_Title") + "</li>";
                    var liHtml = liHtml + "<li>" + $(this).attr("ows_Debtor_x0020_Code") + "</li>";
                    var liHtml = liHtml + "<li>" + $(this).attr("ows_Patient_x0020_Exit_x0020_Date") + "</li>";
                    $("#tasksUL").append(liHtml);
                  });
                }
              });
        });

        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]);
            }
        }
    </script>
    <ul id="tasksUL"/>
</div>
</asp:Content>
Coordinator
Apr 18, 2013 at 4:56 PM
Edited Apr 20, 2013 at 4:41 PM
So the success of the first PServices call tells us that the script references are good and that it's possible to request information from SharePoint. So far, so good.

What are you seeing as returned results in the third chunk of code with GetListItems? I find it's easiest to look at the results in the Net tab with Firebug.

M.
Apr 18, 2013 at 11:39 PM
Edited Apr 19, 2013 at 12:26 AM
Thanks Marc for the tip, I have been on IE with SharePoint work majority of the time and switching back to Firefox with Firebug provides a more interesting view than the Developer tools...but I digress...

It can access web successfully, but when it tries the list.asmx it gives server error 500. Looking deeper it is saying the list cannot be found.

I know that it exists as it will find it when placed within the website page, with same code.

I demonstrated using the web = parentContext.get_web() to perform operations within an app on the true site collection (not the Napa environment)...so it can access and I have put permissions on the app at Tenant level, full control, just to ensure no blockages for now.

I have tried in the code typing the site path directly (https://mysite.sharepoint.com/lcm) but that doesn't seem to change it and I also tried weburl: 'http://mysite.sharepoint.com/lcm/_vti_bin/lists.asmx'
but still "not finding the list" :(
Apr 19, 2013 at 12:28 AM
Edited Apr 19, 2013 at 12:50 AM
I have now updated to use sentence case consistently for the spHostUrl and webURL variables, plus the subsite name (LCM).

My updated code is not longer giving the not found, but instead "302 found" and does not return any results or other errors :(
        var context;
        var web;
        var spHostUrl;
        var parentContext;

        $(document).ready(function () {
            var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
            context = new SP.ClientContext.get_current();
            parentContext = new SP.AppContextSite(context, spHostUrl);
            web = parentContext.get_web();
            jQuery.support.cors = true;

            $().SPServices({
                operation: "GetListItems",
                async: false,
                webURL: spHostUrl + '/LCM',
                listName: "Brisbane Inbox",
                CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='Debtor_x0020_Code' /><FieldRef Name='Patient_x0020_Exit_x0020_Date' /></ViewFields>",
                completefunc: function (xData, Status) {
                  $(xData.responseXML).SPFilterNode("z:row").each(function() {
                    var liHtml = "<li>" + $(this).attr("ows_Title") + "</li>";
                    var liHtml = liHtml + "<li>" + $(this).attr("ows_Debtor_x0020_Code") + "</li>";
                    var liHtml = liHtml + "<li>" + $(this).attr("ows_Patient_x0020_Exit_x0020_Date") + "</li>";
                    $("#tasksUL").append(liHtml);
                  });
                }
              });
        });

        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]);
            }
        }
Apr 19, 2013 at 12:58 AM
Image
Coordinator
Apr 20, 2013 at 4:45 PM
It looks like you are close. The webURL should point to the site (as you're trying to do).

What I would probably do next is to try running the SPServices call and debug through to see exactly how the spHostUrl value is set and then watch the Net traffic to see what's off.

M.
Apr 21, 2013 at 2:56 AM
As I don't normally use firebug, I am not sure what I am looking for on .net traffic?

If I do an alert for spHostUrl it shows my correct destination website where the list is (ie. root site collection + /lcm subsite). So webURL is setting correctly.
Coordinator
Apr 22, 2013 at 4:26 PM
You could also use Fiddler or the IE Developer Tools, but I like Firebug best for this sort of thing.

What you'll want to look at is the whole packet of data going to the server to see that it contains what you expect. Sometimes the Net tab will also have more indication of what the specific problem is.

M.
Oct 8, 2013 at 6:48 PM
Edited Oct 8, 2013 at 7:28 PM
Can I ask if this is SP Hosted app? Are these lists in the App Web or the Host Web? Based on your code, it looks like you are trying to access items on the host web. I have tried to do this, but I don't think it will ever work that way. I tested a simple call to a "Get List" action and this works fine an the App Web with a known list, but if you do this on the Host Web, you will just get an error page returned as you are not able to access the Host Web in this manner. To me, that is one of the drawbacks of apps.
Oct 29, 2013 at 8:38 PM
Edited Oct 29, 2013 at 8:39 PM
Has anyone resolved this issue? I'm attempting to read a list from the Host Web with a Cloud App. The Web URL is correct, but the response from the SOAP service is "undefined". Everything appears to be correct.

Thanks in advance.

C
Oct 30, 2013 at 12:18 PM
There are some things that you can check for, but I stated earlier that some if not most functions will not work against the Host web when doing this. You can set your app to a higher permission requirement which forces the user to trust the app. This gives it more permissions. I have had some success reading from the Host web doing this, but not updating it yet as I have not been able to do that. It always resolves back to the App web and updates that. If I should find some success, I will post it back here.

Regards,
Dan
Oct 30, 2013 at 2:44 PM
I thinks what is going in here is that Apps run in a different URL (domain) and this when attempting to acces the host Web, you are actually going cross domain. That's not going to work well unless, as pointed above, you elevate privileges.

In SP2013, looks like MS realize this and they introduced a REST api that does allow secure cross domain communications (I believe from registered apps only).
Here is a link that describes its usage:


You want to review the section titled 'Using the Cross-Domain JavaScript Library'

/Paul


--

_________
Paul T