Pnpjs: item.breakRoleInheritance(false) is not a function

Created on 1 Oct 2019  路  6Comments  路  Source: pnp/pnpjs

Category

  • [ ] Enhancement
  • [x] Bug
  • [ ] Question
  • [ ] Documentation gap/issue

Version

Please specify what version of the library you are using: [ 1.2.6 ]

Please specify what version(s) of SharePoint you are targeting: [ SharePoint Online ]

Expected / Desired Behavior / Question

const singleItem = await sp.web.lists
    .getById("00000000-0000-0000-0000-00000000") // dummy
    .items
    .getById(1)
    .get();

singleItem.breakRoleInheritance(false);

This last line should break the inheritance of permissions from the list.

Observed Behavior

Following error is thrown on executing the code above:

_Uncaught (in promise) TypeError: singleItem.breakRoleInheritance is not a function_

Steps to Reproduce

I get a correct result running the query:

const singleItem = await sp.web.lists
    .getById("00000000-0000-0000-0000-00000000") // dummy
    .items
    .getById(1)
    .get();

But executing following line produces the error:

singleItem.breakRoleInheritance(false);

It also doesn't work when explicitly casting the result to Item, which extends from SharePointQueryableSecurable (which is where the method is defined).

code not a bug question

Most helpful comment

Hi @Abbas-627,

You're holding it wrong.

await sp.web.lists
    .getById("00000000-0000-0000-0000-00000000") // dummy
    .items
    .getById(1)
    .breakRoleInheritance(false);

All 6 comments

Hi @Abbas-627,

You're holding it wrong.

await sp.web.lists
    .getById("00000000-0000-0000-0000-00000000") // dummy
    .items
    .getById(1)
    .breakRoleInheritance(false);

Hi @Abbas-627,

You're holding it wrong.

await sp.web.lists
    .getById("00000000-0000-0000-0000-00000000") // dummy
    .items
    .getById(1)
    .breakRoleInheritance(false);

Hi @koltyakov

Thank you for your quick response. I got this working but now I have another problem/question then.
What if I use filter and have multiple items to break the inheritance from. And also, I need to add a role-assignment to the item afterwards. My initial code was:

const listItems = await sp.web.lists
    .getById("GUIDTOLIST")
    .items
    .filter(`Identifier eq ${identifier}`)
    .get();

for(const item of listItems) {
    await item.breakRoleInheritance(false);
    await item.roleAssignments.add(userId, roleDefId);
}

But obviously this won't work. Is there a way to do this? Is this possible using batching, and how?

Thanks in advance!

Hi @Abbas-627,

You got precessing each item individually, that's correct, e.g. by getting per ID:

const list = sp.web.lists.getById("GUIDTOLIST");
const listItems = await list.items
    .select('Id')
    .filter(`Identifier eq ${identifier}`)
    .get();

for (const item of listItems) {
    await list.items.getById(item.Id).breakRoleInheritance(false);
    await list.items.getById(item.Id).roleAssignments.add(userId, roleDefId);
}

Hi @koltyakov

Thanks again for your answer. It works and now I was only wondering if this would be more performant by using a batch, like so:

const list = sp.web.lists.getById(listId);
const listItems = await list.items
    .select('Id')
    .filter(`Identifier eq ${identifier}`)
    .get();

let batch = sp.web.createBatch();
for (const item of listItems) {
    await list.items.getById(item.Id).breakRoleInheritance(false);
}
await batch.execute();

batch = sp.web.createBatch();
for (const item of listItems) {
    await list.items.getById(item.Id).roleAssignments.add(userId, roleDefId);
}
await batch.execute();

First, I break the inheritance in batch for all items and in the second batch, I add the role-assignments to all the items. Is this a clean solution?

Thanks in advance!

Using batches can be more effective, but not necessarily. Batches are executed on a server sequentially, so it can be a single batch for breaking inheritance and permissions assignment.

Regards your code sample, batches do not work this way, you're actually not batching anything. Please search for inBatch usage, there are tons of samples with batches in sister issues.

I'd also encourage not converting issues in a chat, mixing different questions together. There is a Gitter chat for random questions. Thanks!

My code posted here was wrong, I used inBatch in my code, also without the await in the loop:

batch = sp.web.createBatch();
for (const item of listItems) {
    list.items.getById(item.Id).inBatch(batch).roleAssignments.add(userId, roleDefId);
}
await batch.execute();

But this issue may be closed as my initial problem is solved. Sorry for mixing things up. Again, thanks for your help!

Was this page helpful?
0 / 5 - 0 ratings