Pnpjs: Site name when working with batch

Created on 25 Apr 2018  路  4Comments  路  Source: pnp/pnpjs

Category

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

Version

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

Expected / Desired Behavior / Question

I was working with batching for updating lists as per documentation at link below and expected to be able to batch add/update items

https://github.com/pnp/pnpjs/blob/37f54d4ac5544315e65579d8850f2b4b1ab94fe5/packages/sp/docs/items.md

Observed Behavior

I kept getting an error back from each request with the message below.

Error: Error making HttpClient request in queryable: [400] Bad Request

Eventually after poking around I discovered it was because when creating my pnp web object the URL I was using didn't 100% match the site name. I was able to use the web object to query the list to get list items or the entity name but it broke when it came to using the batch request, see examples below based on a site called HR-Dev. The only difference is a lower case 'd' in the Url

Broken Example
const webUrl:string = "https://tenantname.sharepoint.com/sites/HR-dev";
const listName:string = "Test List"
const rootWeb = new pnp.Web(webUrl);
const list = rootWeb.lists.getByTitle(listName);
//get entity name
const listEntityName = await list.getListItemEntityTypeFullName();

  let batch = rootWeb.createBatch();

  const numberOfItems:number = 10;

  for(var index=0;index<numberOfItems;index++)
  {            
    list.items.inBatch(batch).add(
    { 
        Title: `Test ${index}`
    }, 
    listEntityName).then(b => 
    {
        console.log(b);
    }).catch((e) =>
    {            
        console.log(e);
    });
  }

  batch.execute().then(d => 
  {
      console.log(d);
      console.log("Done");
  }).catch((e) =>
  {          
      console.log(e);
  });

Working Example
const webUrl:string = "https://tenantname.sharepoint.com/sites/HR-Dev";
const listName:string = "Test List"
const rootWeb = new pnp.Web(webUrl);
const list = rootWeb.lists.getByTitle(listName);
//get entity name
const listEntityName = await list.getListItemEntityTypeFullName();

  let batch = rootWeb.createBatch();

  const numberOfItems:number = 10;

  for(var index=0;index<numberOfItems;index++)
  {            
    list.items.inBatch(batch).add(
    { 
        Title: `Test ${index}`
    }, 
    listEntityName).then(b => 
    {
        console.log(b);
    }).catch((e) =>
    {            
        console.log(e);
    });
  }

  batch.execute().then(d => 
  {
      console.log(d);
      console.log("Done");
  }).catch((e) =>
  {          
      console.log(e);
  });
code answered question

Most helpful comment

@patrick-rodgers speaking of docs, maybe the fact that batch is case-sensitive might be one of those things that should be highlighted somewhere :/

All 4 comments

Hey @raymondlittle100,

Definitely, an interesting issue, have not met this before.

It looks not to be a bug which we can't fix in the library so far. The lib behaves as it should be and as expected. It's not an issue in other methods where REST API is not sensitive to the casing.

Whereas $batch API seems to expect web URLs with the correct casing in the multipart body, otherwise, returns 400 Bad Request in response:

--batchresponse_354bb07a-3e31-41d1-b8cb-cf8226fafaa7
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 400 Bad Request
CONTENT-TYPE: application/json;odata=minimalmetadata;streaming=true;charset=utf-8

{"odata.error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"Invalid request."}}}

In this situation, I can only recommend not to mismatch the URLs, receive URIs from the context variables, etc.

Going to close this as answered. Batches just work this way, they are the same way for header casing.

@patrick-rodgers speaking of docs, maybe the fact that batch is case-sensitive might be one of those things that should be highlighted somewhere :/

Hello,
I'm facing exactly the same issue.

I'm developing a SPFx Webpart and in my I do not open a new web passing the URL, I simply use the spfx context.

As documented I setup SP library in my webpart init method:

sp.setup({
        spfxContext: this.context
      });

and then I create the batch with this code:

        let list = sp.web.lists.getByTitle("XYZ");
        list.getListItemEntityTypeFullName().then(entityTypeFullName => {

            let batch = sp.web.createBatch();
...
...

In the Chrome DevTools I clearly see that the weburl used in the batch is all lowercase and this makes the call fail.

What could be a workaround in my case?

Was this page helpful?
0 / 5 - 0 ratings