0

I have my app and my list in my site contents like so:

enter image description here

From my app, I'd like to read, write, and manipulate the data from TestList.

The contents of TestList are like so:

enter image description here

I've been trying to read it using this:

function setup() {

    var context = SP.ClientContext.get_current();

    var lists = context.get_web().get_lists();
    var list = lists.getByTitle('TestList');
    var listItem = list.getItemById("Title1"); // is Id the list title?

    context.load(listItem);
    context.executeQueryAsync(onLoadSuccess, onLoadFail);

    console.log(listItem);

}

function onLoadFail(sender, args) {
    alert(args.get_message());
    console.log(args.get_message());
};

As well as some other methods outlined here and here, but I'm constantly greeted by the error:

List 'TestList' does not exist at site with URL 'https://mysite.sharepoint.com/sites/developer/TestApp'.

I think it could have something to do with TestList being an app within the same directory level as TestApp, not a list within TestApp which is why I included the pictures. However, I can't figure out how to embed TestList within TestApp.

My other concern with making the list within the app would be that whenever I update and redeploy TestApp, it would wipe any new updates to TestList.

Can someone see what I'm doing wrong or offer some suggestions? Thanks in advance.

  • 1
    var listItem = list.getItemById("Title1"); // is Id the list title? - imho instead "Title1" there should be listitem ID number – Gennady G Feb 2 '15 at 20:01
  • @GennadyG that's not an opinion, it's a fact! getItemById expects an integer that represents the item's numerical ID: msdn.microsoft.com/en-us/library/office/… – John-M Feb 3 '15 at 2:11
  • @John-M so in my example TestList, what's the Id for each row? Is it just 0 and 1? – Charles Clayton Feb 3 '15 at 16:27
  • Each item has a unique ID number, similar to a record in a database (although a sharepoint list isn't a database). IDs can be difficult to work with because it can be difficult to know beforehand what ID you should be looking for -- the easiest way to see an item ID in your list is to look at the item link in the list view, it should have a parameter that says ...&ID=<number>&... the <number> is the item ID. It's usually easier to get all of the list items and enumerate them for smaller lists, you'll have to break out a CAML query or REST $filter for more complicated scenarios – John-M Feb 3 '15 at 16:34
  • Hmm. Thank you! I'm in this sort of frustrating situation now where I got the ListCollection, then did query to get my List, then did a CAML query to get my ListItemCollection, then did a get_item(0) to get a ListItem but I just can't figure out how to index or access any of the actual data in my list in a clean way. – Charles Clayton Feb 3 '15 at 16:54
1

Your hunch here is correct - within an app the client context stuff will return the app's context, not the host context.

Here's one example of how to get the host context from an app:

(See http://www.mavention.com/blog/sharePoint-app-reading-data-from-host-web for source)

The first step is to load required scripts and pull in the URL parameters - you might already be doing this, but note how this example code also loads in a RequestExecutor file. That file is what handles all of the cross-web stuff.

var web;
var hostweburl;
var appweburl;

function sharePointReady() {
   hostweburl =
        decodeURIComponent(
            getQueryStringParameter('SPHostUrl')
    );
   appweburl =
       decodeURIComponent(
           getQueryStringParameter('SPAppWebUrl')
    );

    var scriptbase = hostweburl + '/_layouts/15/';

    $.getScript(scriptbase + 'SP.Runtime.js',
        function () {
            $.getScript(scriptbase + 'SP.js',
                function () { $.getScript(scriptbase + 'SP.RequestExecutor.js', printAllListNamesFromHostWeb); }
            );
        }
    );
}

function getQueryStringParameter(param) {
    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] == param) {
            return singleParam[1];
        }
    }
}

Next up, actually accessing the host context:

function printAllListNamesFromHostWeb() {
    var context;
    var factory;
    var appContextSite;
    var collList;

    context = new SP.ClientContext(appweburl);
    factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
    context.set_webRequestExecutorFactory(factory);
    appContextSite = new SP.AppContextSite(context, hostweburl);

    this.web = appContextSite.get_web();
    collList = this.web.get_lists();
    context.load(collList);

    context.executeQueryAsync(
        Function.createDelegate(this, successHandler),
        Function.createDelegate(this, errorHandler)
    );

    function successHandler() {
        var listInfo = '';
        var listEnumerator = collList.getEnumerator();

        while (listEnumerator.moveNext()) {
            var oList = listEnumerator.get_current();
            listInfo += '<li>' + oList.get_title() + '</li>';
        }

        document.getElementById("message").innerHTML = 'Lists found:<ul>' + listInfo + '</ul>';
    }

    function errorHandler(sender, args) {
        document.getElementById("message").innerText =
            "Could not complete cross-domain call: " + args.get_message();
    }
}

As you can see, the only extra thing that needs to be done is the setup of the 'hostContextSite' through the Request Executor object. Everything else here is basically the same.

Hopefully this helps! You should check out the blog I took the sample code from for a little more explanation.

0

Ted N's answer worked after a bit of tweaking, but this did as well and is much simpler.

function getList() {

    var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
    currentcontext = new SP.ClientContext.get_current();
    hostcontext = new SP.AppContextSite(currentcontext, hostUrl);
    web = hostcontext.get_web(); // hostcontext instead of currentcontext

    var lists = web.get_lists();
    var list = lists.getByTitle(LIST_NAME);

    listItemCollection = list.getItems(""); // use CAML query for specific requests

    console.log(listItemCollection);

    context.load(listItemCollection);
    context.executeQueryAsync(sharePointReady, queryFailed);

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.