Breeze - Get SharePoint AttachmentFiles from List using Expand?

1.1k views Asked by At

I am using Breeze with a SharePoint Online list, which support attachments. The Breeze query, correctly calls expand and I can see through Browser and Fiddler, that JSON is returned with the attachment data in it. However, the entities created in Breeze JavaScript don't contain data for AttachmentFiles. Its always Null. Is this something the SP Adapter just doesn't support, or am I defining the AttachmentFiles and List entities incorrectly. I have tried numerous ways to define relationship, using complextype and navigation, with autogen ID and without, but I am coming up stumped.

Rest Request looks like this: /_api/web/lists/getbytitle('Contacts')/items?$expand=Author/Id,AttachmentFiles&$select=Id,AuthorId,FirstName,Title,Email,Author,AttachmentFiles ,Author/UserName

Attached is a view of the JSON returned, and the current Breeze entities mapped.

Snippet from entities

    //attachments
addType({
  name: 'AttachmentFiles',
  dataProperties: {
    ServerRelativeUrl: {
      nullable: false
    },
    FileName: {
      nullable: false
    }

  }
});

// create entity for contacts
addType({
  name: 'Contacts',
  defaultResourceName: 'getbytitle(\'Contacts\')/items',
  dataProperties: {
    Id: {
      type: breeze.DataType.Int32
    },
    AuthorId: {
      type: breeze.DataType.Int32
    },
    FirstName: {
      nullable: false
    },
    Title: {
      nullable: false
    }, // this is actually the last name field in the list
    Email: {
      nullable: false,
      validators: [breeze.Validator.emailAddress()]
    },
    Author: {
      complexTypeName: "Author"
    }
  },
  // Let model.validation add the requireReferenceEntity validators
  navigationProperties: {
    AttachmentFiles: {
      type: 'AttachmentFiles',
      hasMany: true
    }
  }
});

See JSON response below

{
"d": {
    "results": [
        {
            "__metadata": {
                "id": "388762a5-a565-4033-af90-5a2ea4cb1894",
                "uri": "https://foo-616175366e015f.sharepoint.com/sites/DevSIte/BreezeSP2013Sample/_api/Web/Lists(guid'df211835-f6df-4bb0-b7f0-0995c6ff8562')/Items(1)",
                "etag": "\"3\"",
                "type": "SP.Data.ContactsListItem"
            },
            "AttachmentFiles": {
                "results": [
                    {
                        "__metadata": {
                            "id": "https://foo-616175366e015f.sharepoint.com/sites/DevSIte/BreezeSP2013Sample/_api/Web/Lists(guid'df211835-f6df-4bb0-b7f0-0995c6ff8562')/Items(1)/AttachmentFiles('8328787dc792224f625c9645a45d01aa.jpg')",
                            "uri": "https://foo-616175366e015f.sharepoint.com/sites/DevSIte/BreezeSP2013Sample/_api/Web/Lists(guid'df211835-f6df-4bb0-b7f0-0995c6ff8562')/Items(1)/AttachmentFiles('8328787dc792224f625c9645a45d01aa.jpg')",
                            "type": "SP.Attachment"
                        },
                        "FileName": "8328787dc792224f625c9645a45d01aa.jpg",
                        "ServerRelativeUrl": "/sites/DevSIte/BreezeSP2013Sample/Lists/Contacts/Attachments/1/8328787dc792224f625c9645a45d01aa.jpg"
                    },
                    {
                        "__metadata": {
                            "id": "https://foo-616175366e015f.sharepoint.com/sites/DevSIte/BreezeSP2013Sample/_api/Web/Lists(guid'df211835-f6df-4bb0-b7f0-0995c6ff8562')/Items(1)/AttachmentFiles('Screen Shot 2015-04-23 at 10.28.35 AM.png')",
                            "uri": "https://foo-616175366e015f.sharepoint.com/sites/DevSIte/BreezeSP2013Sample/_api/Web/Lists(guid'df211835-f6df-4bb0-b7f0-0995c6ff8562')/Items(1)/AttachmentFiles('Screen%20Shot%202015-04-23%20at%2010.28.35%20AM.png')",
                            "type": "SP.Attachment"
                        },
                        "FileName": "Screen Shot 2015-04-23 at 10.28.35 AM.png",
                        "ServerRelativeUrl": "/sites/DevSIte/BreezeSP2013Sample/Lists/Contacts/Attachments/1/Screen Shot 2015-04-23 at 10.28.35 AM.png"
                    }
                ]
            },
            "Author": {
                "__metadata": {
                    "id": "1fdc1547-d439-42bd-b3aa-b41e92c8ec6f",
                    "type": "SP.Data.UserInfoItem"
                },
                "UserName": "[email protected]"
            },
            "Id": 1,
            "ID": 1,
            "Title": "Alanso",
            "AuthorId": 1073741823,
            "FirstName": "Fernando",
            "Email": "[email protected]"
        }
    ]
}

}

1

There are 1 answers

5
Ward On

I do see problems here ... that you can cure.

First, I'd like to call your attention to "Debugging query results" documentation which has many tips to help you diagnose what's going on. Not all of them are applicable but they are valuable clues in there.

I'm curious if your EntityManager has any entities of type "AttachmentFiles". I rather doubt it. You might check.

Regardless, two observations leap out at me:

  1. The AttachmentFiles type does not have a key property, the property that uniquely identifies an instance of this type. Every EntityType must have at least one key property. The MetadataHelper can detect some keys by convention but there is no obvious candidate in your AttachmentFiles. If there is one (and I don't see it), you'll have to specify it.

I'm assuming that you're using the MetadataHelper defined in Breeze Labs breeze.metadata-helper.js to write your metadata rather than the raw Breeze API for that purpose. It looks like you are doing so ... and that's a good thing.

  1. Your Contacts type identifies a One-to-Many navigation to AttachmentFiles but doesn't specify the foreign key relationship in AttachmentFiles that would link instances of AttachmentFiles back to Contacts. Thus even if Breeze created AttachmentFiles instances from this JSON payload, it could not associate them with any instances of Contacts

I don't see anything in the data that supports the notion that AttachmentFiles are actually entities. They seem to be embedded in the Contact type.

There IS a way to represent that. But I'd want some confirmation before I went down that road. Maybe you can clarify some of the points I raised here before we propose next steps.