by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jun 18 2019 13:42
    patrick-rodgers closed #830
  • Jun 18 2019 13:42
    patrick-rodgers opened #830
  • Jul 10 2018 12:58
    patrick-rodgers closed #751
  • Jul 10 2018 12:58
    patrick-rodgers closed #753
  • Jul 10 2018 12:58
    patrick-rodgers closed #758
  • Jul 10 2018 12:57
    patrick-rodgers closed #815
  • Jul 10 2018 12:57
    patrick-rodgers closed #823
  • Jul 10 2018 12:57
    patrick-rodgers closed #824
  • Jul 10 2018 12:57
    patrick-rodgers closed #825
  • Jul 10 2018 12:57
    patrick-rodgers closed #829
  • Jul 10 2018 12:57
    patrick-rodgers commented #829
  • Jul 10 2018 11:06
    Mike-tech opened #829
  • Jul 06 2018 18:26
    koltyakov labeled #828
  • Jul 06 2018 18:21
    ken-harris commented #828
  • Jul 06 2018 18:21
    ken-harris closed #828
  • Jul 06 2018 17:51
    koltyakov labeled #828
  • Jul 06 2018 17:51
    koltyakov commented #828
  • Jul 06 2018 14:23
    ken-harris opened #828
  • Jul 06 2018 13:18
    koltyakov labeled #827
  • Jul 06 2018 13:18
    koltyakov labeled #827
Eirik Brandtzæg
@eirikb
Andrew Koltyakov
@koltyakov
Ensures guid values are represented consistently as "ea123463-137d-4ae3-89b8-cf3fc578ca05" =)
image.png
Just an internal helper to extract and sanitize guids
Does it lead to some edge cases issues?
Eirik Brandtzæg
@eirikb
No, just that if you provide a valid guid you get the guid back, and if you provide an invalid guid you still get the same guid back
Andrew Koltyakov
@koltyakov
I'd guess it's by design - invalid are returned as is, when guid finger print is presented the string is trimmed from other possible representations as {...}, /GUID('...')/
I think it covers {} /GUID('')/ cases mostly
rather than has any aims to throw an exception with incorrect guids formats
Eirik Brandtzæg
@eirikb
I see. Thanks :)
Just seemed odd. Was browsing through the code
I was looking for taxonomy, the utility setItemMetaDataMultiField but I can't find it in 2.x
Andrew Koltyakov
@koltyakov
Taxonomy support was dropped in v2, there was an article in the docs for the reasoning of that action. Looks that the method was a part of it.
Eirik Brandtzæg
@eirikb
Ok. Thanks
Valeras Narbutas (Macaw)
@ValerasNarbutas
Good day all, I have a question, might be not realy related to pnpjs, is anyone familiar how https://docs.microsoft.com/en-us/sharepoint/dev/ is built? in particular which part is responsible for generating left side meniu from git repo md files? Maybe anyone knows better chanel to ask?
Valeras Narbutas (Macaw)
@ValerasNarbutas
I found my answer.
Astatke
@astatke

This is a question I asked on Github, https://github.com/pnp/pnpjs/issues/1078#issuecomment-591804936, but I am still unable to resolve it.
Below is the complete js code. I am getting "undefined" while trying to display the Email portion of a People or Group field called
"ServiceContact" that I created on a custom list called Services. FYI, I am implementing this on a SharePoint 2016 web page. Please help?

<script type="text/javascript" src="/scripts/js/es6-promise.auto.min.js"></script>
<script type="text/javascript" src="/scripts/js/fetch.js"></script>
<script type="text/javascript" src="/scripts/js/pnp.min.js"></script>

<div>
<div>
<p id="countid">No Information Management services found.</p>
<table width="100%" cellpadding="5" cellspacing="2" class="main-table" id="Main">
</table>
</div>
</div>

<script type="text/javascript">
var filterValue = "Expire eq 'No'&ServiceOwner eq 'Information Management'&$orderby=Title asc";
$pnp.sp.web.lists.getByTitle('Services')
.items
.select('Title,ServiceDescription,ServiceDeliveryDetails,ServiceDuration,ServiceContact/EMail')
.expand('ServiceContact')
.filter(filterValue)
.get()
.then(function(result) {


if(result.length > 0)
$('#countid').html("<b>Number of IM Services found:</b> "+ result.length);

for(var i=0; i< result.length; i++){
$("#Main").append(
"<tr><td><h2>" + result[i].Title + '</h2></td></tr>'+
"<tr><td><b>Service Description</b>" + result[i].ServiceDescription + '</td></tr>'+
"<tr><td><b>Delivery Details</b>" + result[i].ServiceDeliveryDetails + '</td></tr>'+
"<tr><td><b>Contact</b>" + result[i].ServiceContact.Email + '</td></tr>'+
"<tr><td><b>Duration</b>" + result[i].ServiceDuration + '</td></tr>'+
"<tr><td><hr></td></tr>");
}
}).catch(function(err){ alert(err);});
</script>

Andrew Koltyakov
@koltyakov
In JS case matters. result[i].ServiceContact.Email should be result[i].ServiceContact.EMail
"Expire eq 'No'&ServiceOwner eq 'Information Management'&$orderby=Title asc" <- this, is btw incorrect too. Condotions should be joined with and or or, but not the &. ServiceOwner eq 'Information Management' is just ends up ignored.
$orderby should not be placed to filter, but .orderBy('Title', true).
I'd recommend using debugger and console to understand why something in JS says it's undefined. This has no connection to the library. If on the learning curve you're not ready for debugger, etc. a trick is to use just console.log() for an object you're not sure about, or printing it in <pre> tag using JSON.stringify(yourObject, null, 2) to see what's in response, etc. Cheers!
Eirik Brandtzæg
@eirikb
In 2x, how would I go about mocking say Items.prototype.get with sp-commonjs?
Eirik Brandtzæg
@eirikb
Horrible, but seems to work:
const { _Items } = require('@pnp/sp-commonjs/items/types');
_Items.prototype.get = async () => [{ Id: 1 }];
Ryan
@Doogibo_gitlab
@eirikb Hey Eirik! You had a question a while ago regarding roleassignments. I am dealing with the same issue and wondering if you found a solution. The issue is to do with roleassignments only returning PrincipalId. I would like PrincipalId and the RoleDefId so that I can determine what permission level the principal has on the item, etc.
Oops. I realize you had the answer right below. .expand('RoleAssignments/RoleDefinitionBindings').select('RoleAssignments/PrincipalId,RoleAssignments/RoleDefinitionBindings').get(); ... very nice. Thank you!
Astatke
@astatke
Thank you so much for helping resolve this issue Andrew :) The primary issue was the lower case "m" I used for the property .EMail.
Eirik Brandtzæg
@eirikb
Can I stub sp recursively? I've tried with sinon, but I'm only able to stub the first part, then I must mock the rest.
Something like this would be awesome (fictional):
when(sp.web.getList('web/Lists/A').items.filter(`Title eq 'yes'`).get).thenReturn([{ Id: 1 }]);
when(sp.web.getList('web/Lists/A').items.filter(`Title eq 'no'`).get).thenReturn([{ Id: 2 }]);
when(sp.web.getList('web/Lists/B').items.filter(`Title eq 'yes'`).get).thenReturn([{ Id: 3 }]);
Eirik Brandtzæg
@eirikb

I made my own, does t his look good?

  const mySp = when(sp);
  mySp.web.getList('web/Lists/A').items.filter(`Title eq 'yes'`).get.thenReturn([{ Id: 1 }]);
  mySp.web.getList('web/Lists/A').items.filter(`Title eq 'no'`).get.thenReturn([{ Id: 2 }]);
  mySp.web.getList('web/Lists/B').items.filter(`Title eq 'yes'`).get.thenReturn([{ Id: 3 }]);
  console.log(1, mySp.web.getList('web/Lists/A').items.filter(`Title eq 'yes'`).get());
  console.log(2, mySp.web.getList('web/Lists/A').items.filter(`Title eq 'no'`).get());
  console.log(3, mySp.web.getList('web/Lists/B').items.filter(`Title eq 'yes'`).get());
  // Prints:
  // 1 [ { Id: 1 } ]
  // 2 [ { Id: 2 } ]
  // 3 [ { Id: 3 } ]

Then I use rewiremock to replace sp with mySp. I could also just replace it with require('@pnp/sp-commonjs').sp = mySp before require my code.
The stubbing hack I made will work in browser and node

Eirik Brandtzæg
@eirikb
I think this works great, tested with @pnp/sp and @pnp/sp-commonjs. Any comment/feedback/questions would be great.
Here is an example:
const test = require('ava');
// Here be magic
require('./bootstrap-test-blackbox');
const { sp } = require('@pnp/sp-commonjs');

async function someExternalModule() {
  const spItem = sp.web.getList('web/Lists/A').items.getById(137);
  const item = await spItem.get();

  await spItem.update({
    Sum: item.Sum + 100
  });
}

test('Summing!', async t => {
  t.plan(1);
  const spItem = sp.web.getList('web/Lists/A').items.getById(137);
  spItem.get.thenReturn({ Sum: 600 });
  spItem.update.thenCall(item => {
    t.deepEqual({ Sum: 700 }, item);
  });

  // This part will be in another file, e.g., index.js in Azure Functions function
  await someExternalModule();
});
Eirik Brandtzæg
@eirikb
I published the thing, hope someone might find it useful: https://github.com/eirikb/when also hope I'm not doing something sinon already can do, except I don't know how
michaelcmelton
@michaelcmelton

trying to install @pnp/sp through npm on a fresh directory. Keeps returning with file not found. @pnp/sp -> @pnp/.sp.DELETE

Full error:

npm ERR! code ENOENT
npm ERR! syscall rename
npm ERR! path /mnt/c/Users/michael.melton/Documents/_DevWork/DeployTool/node_modules/@pnp/sp
npm ERR! dest /mnt/c/Users/michael.melton/Documents/_DevWork/DeployTool/node_modules/@pnp/.sp.DELETE
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, rename '/mnt/c/Users/michael.melton/Documents/_DevWork/DeployTool/node_modules/@pnp/sp' -> '/mnt/c/Users/michael.melton/Documents/_DevWork/DeployTool/node_modules/@pnp/.sp.DELETE'
npm ERR! enoent This is related to npm not being able to find a file.

Windows 10 Linux Subsystem OS

Stefen Hasselberg
@stefen-hasselberg

Evening All
just a quick question, can you use batch to fetch two or three lists at once ?

Thanks

Tomi Tavela
@tavikukko
Yes, only limitation is, it has to inside same site collection.
Stefen Hasselberg
@stefen-hasselberg
@tavikukko
ok I seem to be having some issue trying to make a batch request to multiple list. Below is my code and the error that i'm getting. All the list are within the same site collection so I'm not sure what I have done wrong. it seems to work fine if you change the request to add an item but not a get
import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";


export const fetchInitialData = (): any => {
  return async dispatch => {
    try {
      let batch = sp.createBatch();

      sp.web.lists
        .getByTitle("BusinessUnits")
        .items.inBatch(batch)
        .orderBy("Title")
        .get().then(r => console.log(r))

await batch.execute();
}
catch(error) { console.log(error)} 

Error: Error making HttpClient request in queryable [400] Bad Request ::> {"odata.error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"Invalid request."}}}
    at new HttpRequestError (parsers.js:130)
    at Function.<anonymous> (parsers.js:145)
    at step (tslib.es6.js:99)
    at Object.next (tslib.es6.js:80)
    at fulfilled (tslib.es6.js:70)
Tomi Tavela
@tavikukko
// CTRL/CMD + D to execute the code
import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";

(async () => {

let batch = sp.web.createBatch();

let list = sp.web.lists.getByTitle("Documents").items.inBatch(batch)();

let list2 = sp.web.lists.getByTitle("Images").items.inBatch(batch)()

await batch.execute();

const l = await list;
console.log(l)
const l2 = await list2;
console.log(l2)

})().catch(console.log)
Tomi Tavela
@tavikukko
tested this in SP Editor and it worked ok.
Eirik Brandtzæg
@eirikb
My annual struggle: Azure Functions against SharePoint list subscriptions.
Any good approaches for this? I've been through the lot, wondering how to do it properly
Eirik Brandtzæg
@eirikb
I'm either over-engineering it, or under-engineering it. And neither seems good.
And all solutions have hacks in them
Eirik Brandtzæg
@eirikb
Any good CLI-way to generate TypeScript types from ContentTypes?
Andrew Koltyakov
@koltyakov
Maybe sp-typed-item?
Eirik Brandtzæg
@eirikb
Looked at it, as it was dependency of a vscode generator (same guy).
Didn't quite understand how to use it
Also it didn't seem to give me a content type as a type, just defined as a ct
Eirik Brandtzæg
@eirikb
Nevermind, it works :)
Things like Choice will not be mapped, logically enough as it won't be able to map back directly.
I'll think about this, got my own generator now supporting choice (to enum, and back)
shoaib0077
@shoaib0077
Hello, I am new to pnpjs, i am trying to get items from sharepoint list through pnpjs
I want to filter items where a field value is empty
Andrew Koltyakov
@koltyakov
Hi @shoaib0077, it's mostly about SharePoint REST API rather than PnPjs, PnPjs abstracts many SP nuances, but at the end of the day, it bypassed requests to REST API.
So if you know how it's done in the REST you can easily apply the same to PnPjs's helper.
With empty values and filter: FieldName eq null would work. But some nuances might emerge, none related to the library but SharePoint version (e.g. in old SP versions null comparing didn't work for example, or it could work but with not any field data type).
shoaib0077
@shoaib0077
@koltyakov Perfect! Thank you so much for explaining. I really appreciate your prompt response.
Tarun Dhillon
@tarundhillon
Hi - I have been using the pnpjs on the browser but recently I have been try to use it on nodejs .. https://github.com/SharePoint-NodeJS/pnp-auth/issues/7#issuecomment-607794385 link was useful to get the environment setup .. but I am finding some functions such as sp.web.currentUser.get() and sp.web.lists.getById are working but others such as sp.web.getFolderByServerRelative() and sp.web.folders.getName() are not working and giving an error around invalid argument and folder not found .. both these functions worked perfectly well on the client side .. any ideas on why they aren't working on the server side ? Thanks
Could this be because on the server side I am using sp from @pnp/sp-commonjs as suggested in the link and not from @pnp/sp
if so what would be a workaround ?
Andrew Koltyakov
@koltyakov
@tarundhillon can you create a repository with a minimal scaffolded project which repro the behavior?
There is no getFolderByServerRelative method but getFolderByServerRelativeUrl, getFolderByServerRelativePath.
All of the mentioned work for me in Node.js with no issues:
image.png
Tarun Dhillon
@tarundhillon
@koltyakov thanks for your response... it was a dumb moment for me ... I found that the issue was due to a mix of incorrect location and access issues for the user account.
Clint Lechner
@clechner77
anyone happen to know if you can default ChromeType (Default,TitleOnly, BorderOnly, etc) from within an SPFx web part? Would love to be able to set default values when using web part on a classic site.