SharePoint/PnP-JS-Core

getItem() / get() is changing the Site Url Context..

Closed this issue · 2 comments

Category

[ ] Enhancement
[X] Bug
[ ] Question

Version

Please specify what version of the library you are using: [sp-pnp-js v3.0.7]

Expected / Desired Behavior / Question

Attempting to check published status of elements in the Style Library from a subsite .

let source = "/Style Library/somefile.png";
pnp.sp.site.rootWeb.getFileByServerRelativeUrl(source).getItem().then(item => {
                         item.get().then(itm => { 
                              //do work..
                         });
});

Observed Behavior

when item.get() is executed and the REST call is generated it uses the current web url, not the rootWeb url from the previous request. Item is populated with an incorrect _parentUrl, should be inherited from the initial request, instead of being the currentWebUrl.. The second get request is issued like
item._parentUrl = "http://rootsite/subsite/.." instead of item._parentUrl = "http://rootsite"

item._parentUrl = http://rootsite/subsite/_api/Web/Lists(guid'aef08ce5-e330-4393-997f-43145ccd1b00')/Items(4)

I would expect this to keep the context of the initial call (http://rootsite) would not be replaced with the child site across the second request.

Steps to Reproduce

Create a sub site off of a top level site collection, use the code above to attempt to return the ListItem associated with the source file.

Hi @mrpullen,

Thanks for posting the issue!

Looks like a bug. Please use the following as a temporary workaround:

const sourceUrl = '/Style Library/somefile.png';
sp.site.rootWeb.select('Url').get()
  .then(({ Url }) => new Web(Url))
  .then(web => web.getFileByServerRelativeUrl(sourceUrl).getItem())
  .then(item => item.get())
  .then(console.log);

This is addressed in #809 with the addition of the getRootWeb method. The issue stems from the fact that even though you are referencing the rootweb the call is still happening in the context of the subweb. Meaning the values we get back and use to create the child thing (in your case item) points to the subweb as you found. So while you can pull information from that web it doesn't chain correctly. The getRootWeb method will get a correctly setup Web instance appropriate for chaining. Usage is:

const source = "/Style Library/file.png";
pnp.sp.site.getRootWeb().then(rootWeb => {

    rootWeb.getFileByServerRelativeUrl(source).getItem().then(item => {

        item.get().then(itm => {
            console.log(itm.Name);
        });
    });
});