Repository.retrieveItem(itemPath, callback) not working

I just noticed that the following function is not working as the documentation says in the ICN JavaScript model. Actually it can not be used with a document path.

retrieveItem(itemIdOrPath, itemRetrievedCallback, templateID, version, vsId, objectStoreId, action)

Here is the Knowledge center documentation:

Retrieves the specified ecm.model.ContentItem from the repository.

  • itemIdOrPath: A String value holding the item identifier or item path.
  • itemRetrievedCallback: A callback function called after the item has been retrieved. Will pass a ecm.model.ContentItem object as a parameter.
  • templateID: A string value holding the template Id.
  • version: A string holding the version requested; ie. “current” or “released” (optional).
  • vsId: A string value holding the version series identifier (optional, FileNet P8 only).
  • objectStoreId: A string value holding the object store identifier (FileNet P8 only).
  • action: A string value to pass up to the mid-tier specifying the action being performed (optional).

You can pass a folder or document ID, but you can only pass a folder path, not a document path. This is because in the implementation (I just checked), if the itemIdOrPath start with a /, they do a Factory.Folder.fetchInstance, so there is no way to fetch a document by path with this function. I actually looked in all sources and I didn’t find any services fetching a document by path. (I might be wrong on that though)

Now as a reminder: the path of a document might be confusing anyway since it is not using the DocumentTitle name but the Containment Relationship name, which will be unique. That makes sense since the DocumentTitle doesn’t have to be unique within a folder.

Work around

You have two ways to work around that.

  1. Create your own service calling Factory,Document,fetchInstance which can use a path (it will use the Containment name relationship). This is the most efficient solution since it will do only one call to the server but it requires some extra work since you’ll have to implement a new service.
  2. Use the JavaScript method anyway. Here is what I came up with, but it has to call the server twice, so it will be slower. But you don’t have any extra work to do except using this:
getItemByPath: function (itemPath, repository) {
    var def = new Deferred();
    var parentPath = itemPath.substring(0, itemPath.lastIndexOf("/"));
    var itemName = itemPath.substring(itemPath.lastIndexOf("/") + 1, itemPath.length);
    repository.retrieveItem(parentPath, function (item) {
        item.retrieveFolderContents(false, function (resultSet) {
            if (!resultSet.items || resultSet.items.length == 0) {
                def.resolve(null);
            } else {
                def.resolve(resultSet.items[0]);
            }
        }, null, null, true, null, "", item, {type: "AND", conditions: [
            {name: "{NAME}", condition: "endWith", value: "a.dita"},
            {name: "{NAME}", condition: "startWith", value: "a.dita"}
        ]});
    }, 'Folder');
    return def.promise;
}

However it will fail and display an error to the user if the parent folder does not exist. You might want to combine this with the getFolderSmart I gave you here.

Leave a Reply