Category Archives: PnP-JS-Core

Upgrading sp-pnp-js to 1.0.5

You have already working SharePoint project which is using SharePoint PnP JavaScript Core Component library. (https://github.com/SharePoint/PnP-JS-Core). You want to update it or you accidently updated it from earlier version to 1.0.5.

I have used in this example Patrick Rodgers’ Yeoman sample project (https://www.npmjs.com/package/generator-sp-pnp-js-sample).

Before you will do anyting everything works fine and if you execute gulp build you will get successful build.

update_sp-pnp-js_before_update

Updating sp-pnp-js

Before we can update to new version of the sp-pnp-js package, we need to check how it’s installed to the project. This can be done by checking the project.json file. It has two sections for external packages (dependencies and devDependencies).

update_sp-pnp-js_pnpversion_100

We will execute

npm install sp-pnp-js@latest --save

to update sp-pnp-js to latest version. Note that you need to use –save parameter instead of –save-dev, because sp-pnp-js is in dependencies section instead of devDepencencies.

update_sp-pnp-js_update_sp-pnp-js

You can see that we have now the 1.0.5 version which we were looking for. Now if we will try to build our project, we notice that it will fail. At first everything seems to go fine.

update_sp-pnp-js_build_fails1

but then we can see only red error lines and lots of those.

update_sp-pnp-js_build_fails2

Updating Typescript

Now it’s time to read the manual or something like that. In our case explanation comes from GitHub commit comments. “Updates to TypeScript 2.0”. Ok. What this means? What version we have? It’s easy to find out. You can see it right after gulp build has started. It says that our version is 1.8.10.

update_sp-pnp-js_typescript_version_1_8

Execute

npm install typescript@latest --save-dev

Note that now you need to use –save-dev, because typescript is in devDependencies section.

update_sp-pnp-js_typescript_update

Now everything should work as we have updated TypeScript to required version.

update_sp-pnp-js_build_fails3

Wait!! Why we get all those errors even though we have correct TypeScript version?

update_sp-pnp-js_build_fails4

Removing extra typings

It seems that we have duplicate type definitions for all those typescript files. Previously sp-pnp-js required several external typings before it worked. Now those require typings have been added inside the package.

update_sp-pnp-js_typings

We need to remove external typings. Extra typings can be found from project\typings\ folder.

Execute following commands

typings uninstall whatwg-fetch --global
typings uninstall es6-promise --global

update_sp-pnp-js_typings_uninstall

Now you can execute

gulp build

Everything works now.

update_sp-pnp-js_build_succeeds

PnP-JS-Core samples

This is the part four of my posts about SharePoint client side development using Node.js.

You can see previous parts from here:

During this post we will extend existing PnP Workbench with different common scripts.

Code Template

I have created following template that can be used to test different codes easily. You just need to write your own code after // write code here comment. I have used this template for all example codes here unless I have told otherwise.

var testbench = testbench || {};
testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: Test name</h2>");
        // write code here
    };   
    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_EmptyCode

Web

Here are scripts related to Web.

Show title of the web

var testbench = testbench || {};

testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: getWebTitle</h2>");
        $pnp.sp.web.select("Title").get()
            .then(function(web){
                targetElement.append(web.Title + "<br />");
            })  
            .catch(function(error){ 
                targetElement.append(error + "<br />");
        })
    };   

    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_WebTitleCode

If everything went fine, you should see the title of the web in test bench area.

PnPJsSamples_WebTitleBrowser

Show all properties from web object

This can be useful when you try to see what is current state of the web object.

var testbench = testbench || {};

testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: getWeb</h2>");
        $pnp.sp.web.get()
            .then(function(web){
                for (var key in web) {
                    targetElement.append(key + ": " + web[key] + "<br />");
                }
            })  
            .catch(function(error){ 
                targetElement.append(error + "<br />");
        });
    };   

    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_GetWebCode

If everything went fine, you should see all properties of the current web in test bench area.

PnPJsSamples_GetWebBrowser

Lists

Enumerate all lists from current web

This enumerates all lists from current web and shows all their properties.

var testbench = testbench || {};

testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: enumLists</h2>");
        $pnp.sp.web.lists.select('Id', 'Title').orderBy('Title').get()
            .then(function(listIds) {
                for (var index in listIds) {
                    var l = $pnp.sp.web.lists.getById(listIds[index].Id);
                    l.get()
                        .then(function(list){
                            for (var key in list) {
                                targetElement.append(key + ": " + list[key] + "<br />");
                            }
                            targetElement.append("<hr />");
                        })  
                        .catch(function(error){ 
                            targetElement.append(error + "<br />");
                    });
                }
            })
            .catch(function(error){ 
                targetElement.append(error + "<br />");
        });
    };   

    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_EnumListsCode

If everything went fine, you should see all lists under current web and all properties of the list in test bench area. This is quite long list, so I have taken just a snapshot of the first list.

PnPJsSamples_EnumListsBrowser

Enumerate List Items

Enumerates all items from the selected list.

var testbench = testbench || {};

testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: enumListItems</h2>");
        $pnp.sp.web.lists.getByTitle("Documents").items.get()
            .then(function(items){
                for (var i=0; i < items.length; i++) {
                   for (var key in items[i]) {
                        targetElement.append(key + ": " + items[i][key] + "<br />");
                    }
                    targetElement.append("<hr />");
                }
            })  
            .catch(function(error){ 
                targetElement.append(error + "<br />");
        });
    };   

    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_EnumListItemsCode

If everything went fine, you should see all lists items from the selected list and all properties of each list item in test bench area. This is quite long list, so I have taken just a snapshot of the first list item.

PnPJsSamples_EnumListItemsBrowser

Search

Search sites

This example uses search to list all site collections from the tenant. It lists only those current user has rights.

var testbench = testbench || {};

testbench.tests = function() {
    var targetElement = jQuery("#pnp-test-bench");
    targetElement.empty();

    runCode = function(){
        targetElement.append("<h2>Test: searchSites</h2>");
        $pnp.sp.search('contentclass:sts_site')
            .then(function(searchResult) {
                targetElement.append("Search took " + searchResult.ElapsedTime + "ms to complete.<br />");
                targetElement.append("Total rows " + searchResult.TotalRows + ".<br />");
                targetElement.append("Total rows including duplicates " + searchResult.TotalRowsIncludingDuplicates + ".<br />");
                targetElement.append("<hr />");

                for (var index in searchResult.PrimarySearchResults) {
                    var resultItem = searchResult.PrimarySearchResults[index];
                    for (var key in resultItem) {
                        targetElement.append(key + ": " +resultItem[key] + "<br />");
                    }
                    targetElement.append("<hr />");
                }
            })
            .catch(function(error){ 
                targetElement.append(error + "<br />");
        });
    };   

    return {
        runCode: runCode
    }
};

jQuery('document').ready(function(){
    var t = new testbench.tests();
    t.runCode();
});

PnPJsSamples_SearchSitesCode

If everything went fine, you should see list of search results and all properties of each search result item in test bench area. This is quite long list, so I have taken just a snapshot of the first item.PnPJsSamples_SearchSitesBrowser

Creating a PnP-JS-Core Workbench

This is the third part of my posts about SharePoint client side development using Node.js.

You can see previous parts from here:

During this post we will load Office PnP client side scripts and create simple workbench to test our applications in SharePoint.

Setting up project

Create project

The first this is to create a new project. It’s called PnPTestBench. I have covered these steps more detailed in part 2 so I will just show commands and end result here.

Open Node.js Command Prompt

cd \Source
md PnPTestBench
cd PnPTestBench
npm init

name: pnptestbench
version: (Accept default value)
description: PnP-JS-Core Test Bench
entry point: (Accept default value)
test command:
git repository:
keywords:
author: (Enter your name)
license: (Accept default value)

npm install --save-dev gulp

WebStack_GulpLocalInstall

npm install --save-dev gulp-serve

PnPTestBench_GulpServeInstall

Copy files from existing project

We have already created working gulpfile in our previous project so we can reuse those in this also.

PnPTestBench_CopyFilesSource

PnPTestBench_CopyFilesTarget

Copy gulpfile.js, dev_sharepoint_local.crt and dev_sharepoint_local.key from MyFirstProject folder to PnPTestBench folder.

Add required scripts

Office PnP scripts can be loaded as npm package manager. If you are not familiar with Office PnP, you can go to see more information from their GitHub project page. https://github.com/OfficeDev/PnP-JS-Core

jQuery

npm install jquery --save-dev

PnPTestBench_JQueryInstall

Typings

npm install typings --save-dev

PnPTestBench_TypingsInstall

Sp-pnp-js

npm install sp-pnp-js –save-dev

PnPTestBench_SpPnPInstallSuccess

If you will get following error message “’typings’ is not recognized as an internal or external command and “Failed at the sp-pnp-js@x.x.x postinstall script ‘typings install’.”, you didn’t install typings package before installing sp-pnp-js package.

PnPTestBench_SpPnPInstallFails

Building test bench

Creating folders

Now we have installed required packages to get our project working.

We need to create a new folder called app and couple sub folders for it. This is because gulpfile.js contains reference to it.

md app
md app\scripts
md app\styles

PnPTestBench_CreateAppFolders

Open Visual Studio code

PnPTestBench_OpenVSCode

Creating files

Now we can create one html, style sheet and JavaScript file with following content.

app.css

(This is empty file)

app.js

var testbench = testbench || {};
testbench.tests = function() {
   var targetElement = jQuery("#pnp-test-bench");
   targetElement.empty();

   writeGreeting = function(name) {
      targetElement.append("<h2>Test: writeGreeting</h2>");
      targetElement.append("Hello " + name + "<br />");
   };
   return {
      writeGreeting: writeGreeting
   }
};

jQuery('document').ready(function(){
   var t = new testbench.tests();
   t.writeGreeting("Jani");
});

PnPTestBench_AppJs

index.html

<html>
<head>
<title>SharePoint PnP test bench</title>
<style>
body {
   font-family: Verdana, Geneva, sans-serif;
}
.example {
   margin: 10px;
}
.example .code {
   border: 1px solid lightgray;
   padding: 10px;
   font-family: "Lucida Console", Monaco, monospace;
}
</style>
</head>

<body>
<h1>SharePoint PnP test bench</h1>
<div class="example">
<p>Copy following code to your SharePoint site:</p>
<p class="code">
&lt;script type="text/javascript" src="https://dev.sharepoint.local/scripts/jquery.min.js"&gt;&lt;/script&gt;<br />
&lt;script type="text/javascript" src="https://dev.sharepoint.local/scripts/pnp.min.js"&gt;&lt;/script&gt;<br />
&lt;script type="text/javascript" src="https://dev.sharepoint.local/scripts/app.js"&gt;&lt;/script&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="https://dev.sharepoint.local/styles/app.css" /&gt;<br />
&lt;div id="pnp-test-bench"&gt;&lt;/div&gt;<br />
</p>
</div>
</body>
</html>

PnPTestBench_IndexHtml

Copying library files

But wait… What about pnp javascript file. It’s located in node_modules\sp-pnp-js\dist sub folder, but we are not serving that folder. It doesn’t make sense to serve content from every single library folder. It makes the testing of the application much harder.

We can use Gulp to copy library file from its original location to app\scripts folder.

Open gulpfile.js and add following content to it.

gulp.task('copy-files', function() {
   gulp.src('./node_modules/jquery/dist/jquery.min.js').pipe(gulp.dest('./app/scripts'));
   gulp.src('./node_modules/sp-pnp-js/dist/pnp.min.js').pipe(gulp.dest('./app/scripts'));
});

PnPTestBench_GulpFileJs

Because we don’t modify these files that often, we can copy library files to scripts folder when we add new library files. This is done by executing following command in Node.js Command Prompt.

gulp copy-files

PnPTestBench_GulpCopyFiles

Now we can start our test bench

gulp serve-https

PnPTestBench_GulpServeHttps

Then we need to copy html from the example code block to SharePoint test page. If you are unsure how to do this, check instructions from Getting ready for SharePoint development using node.js: http://salomaa.info/sharepoint/getting-ready-for-sharepoint-development-using-node-js/ posting.

PnPTestBench_Browser

Our test bench works fine. Now we can continue working with it. I have created few test cases that use Office PnP JavaScript Core. I will