Question

I'm developing a SharePoint-hosted app for SharePoint 2013 (in Office365), but I've a problem accessing lists within a SharePoint-hosted app.

My code is well printing the lists, but it only show me the 'Composed Looks' list and the 'Master Page Gallery' lists, I can't access the lists that I've created in my sharepoint site.

And when I try to access the 'Contacts' list (which exists in the sharepoint site where I deploy the app), it got this exception :

List 'Contacts' does not exist at site with URL 'https://mysharepointsite-03ea186502297f.sharepoint.com/SPHostedApp12

It thus seems that my app is running from another site than my main site, and that's why I can't access existing lists from my main website...

Does somebody know how to solve this and access existing lists in the main site?

Thanks a lot !

Here is my App.js code:

'use strict';

var gobbe = window.gobbe || {};

gobbe.Contacts;
gobbe.ContactList = function () {
    // private members
    var createItem = function (lname, fname, bphone) {
        var ctx = new SP.ClientContext.get_current();
        var list = ctx.get_web().get_lists().getByTitle('Contacts');
        ctx.load(list);
        var listItemCreationInfo = new SP.ListItemCreationInformation();
        var newContact = list.addItem(listItemCreationInfo);
        newContact.set_item('Last Name', lname);
        newContact.set_item('First Name', fname);
        newContact.set_item('Business Phone', bphone);
        newContact.update();
        ctx.executeQueryAsync(success, error);
    },
    readAll = function () {
        // Not implemented
    },
    readAllSuccess = function () {
        // Not implemented
    },
    updateItem = function () {
        // Not implemented
    },
    updateItem = function (id, lname, fname, bphone) {
        // Not implemented
    },
    removeItem = function (id) {
        // Not implemented
    },
    success = function () {
        readAll();
    },
    error = function (sender, args) {
        alert(args.get_message());
    }

    // public interface
    return {
        createContact: createItem,
        updateContact: updateItem,
        deleteContact: removeItem
    }
}();

gobbe.Collections = function () {
    // private members
    var site,
        listCollection,

        getListCollection = function () {
            var ctx = new SP.ClientContext.get_current();
            site = ctx.get_web();
            ctx.load(site);
            listCollection = site.get_lists();
            ctx.load(listCollection,     'Include(Title,Id,Fields.Include(Title,Description))');
        ctx.executeQueryAsync(success, failure);
        },

        success = function () {
            var html = [];

            // List Information
            html.push('<ul>');
            var listEnumerator = listCollection.getEnumerator();
            while (listEnumerator.moveNext()) {
                // List Title
                html.push('<li>');
                html.push(listEnumerator.get_current().get_title());
                html.push('<ul>');

                // Fields Names
                var fieldEnumerator =     listEnumerator.get_current().get_fields().getEnumerator();
                while (fieldEnumerator.moveNext()) {
                    html.push('<li>');
                    html.push(fieldEnumerator.get_current().get_title());
                    html.push('</li>');
                }

                html.push('</ul></li>')
            }
            html.push('</ul>');

            // Show results
            $('#displayDiv').html(html.join(''));
        },

        failure = function (sender, args) {
            alert(args.get_message());
        }

    // public interface
    return {
        execute: getListCollection
    }
}();

$().ready(function () {
    // Show lists
    gobbe.Collections.execute();

    // Try to add a contact
    gobbe.ContactList.createContact('Cox', 'Brian', '555-555-5555');
    alert('Contact Created!');

    // Update it
    gobbe.ContactList.updateContact(1, 'Cox', 'Brian', '111-111-1111');
    alert('Contact Updated!');

    // Delete it
    gobbe.ContactList.deleteContact(1);
    alert('Contact Deleted!');
});
Was it helpful?

Solution

Apps work in a different domain as compared to your host web. So, its a cross domain call when you try to access some list which resides in your host web from your app web. Normally browsers don't allow to make these cross domain calls for security reasons. However, in apps, to interact with host web, there is a library called SP.RequestExecutor.js, which is a cross domain libarary that you can use to make these calls. Please have a look at the following links that will help you in making these cross domain calls to access host web data inside an app web.

http://msdn.microsoft.com/en-in/library/fp179927.aspx

http://www.mavention.com/blog/sharePoint-app-reading-data-from-host-web

http://blogs.msdn.com/b/officeapps/archive/2012/11/29/solving-cross-domain-problems-in-apps-for-sharepoint.aspx

Hope that helps.

OTHER TIPS

It sounds like that you forgot to give your app permissions: List 'Contacts' does not exist at site with URL.

When you install an app you will be asked for the rights to access a specific library or list for example.

You will have to add something like this... Example of what the markup looks like in an app manifest:

<AppPermissionRequests> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"/></AppPermissionRequests>

To access the list from Host web you would need to rely on the "standard tokens" and then use eithe JSOM or REST APi to access data.

 //Get the URI decoded URLs.
                hostweburl =
                    decodeURIComponent(
                        getQueryStringParameter("SPHostUrl")
                );
                appweburl =
                    decodeURIComponent(
                        getQueryStringParameter("SPAppWebUrl")
                );

Then you could use something like this:

 // Initialize the RequestExecutor with the app web URL.
                executor = new SP.RequestExecutor(appweburl);

                // Issue the call against the host web.
                // To get the title using REST we can hit the endpoint:
                //      app_web_url/_api/SP.AppContextSite(@target)/web/title?@target='siteUrl'
                // The response formats the data in the JSON format.
                // The functions successHandler and errorHandler attend the
                //      success and error events respectively.
                executor.executeAsync(
                    {
                        url:
                            appweburl +
                            "/_api/SP.AppContextSite(@target)/web/title?@target='" +
                            hostweburl + "'",
                        method: "GET",
                        headers: { "Accept": "application/json; odata=verbose" },
                        success: successHandler,
                        error: errorHandler
                    }
                );
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top