Category: Technology

  • Get count of items/files in list/document library in SharePoint Online with SPFx

    In SharePoint Online, when we view Site Contents, internally a call is made to the end point /_api/web/AppTiles to get the count of items/files in list/document library that the current site collection has. We can call this API in SPFx webpart to get these details. Below is the sample code.

    import { SPHttpClient, SPHttpClientResponse, SPHttpClientConfiguration } from '@microsoft/sp-http';
    
    this.context.spHttpClient.get(`${this.context.pageContext.web.absoluteUrl}/_api/web/AppTiles`, SPHttpClient.configurations.v1)
      .then((response: SPHttpClientResponse) => {
        response.json()
          .then((responseJSON: any) => {
            console.log(responseJSON); // Gets all the list and document library details in JSON
          })
          .catch(error => {
            console.log(error);
          });
      })
      .catch(error => {
        console.log(error);
      });

    this.context refers to WebPartContext in the BaseClientSideWebPart class. The output will looks something like below JSON snippet. There is a lot of detail here which we can filter using $select. The attributes we require are Title and ChildCount.

    {
        "@odata.context": "https://mysite.sharepoint.com/sites/mysitecollection/_api/$metadata#AppTiles",
        "value": [
          {
            "@odata.type": "#SP.AppTile",
            "@odata.id": "https://mysite.sharepoint.com/sites/mysitecollection/_api/SP.AppTile0aab34a5-8bb4-4d5e-bac0-90841a08dd34",
            "@odata.editLink": "SP.AppTile0aab34a5-8bb4-4d5e-bac0-90841a08dd34",
            "AppId": "58de69fc-9e3f-4375-af44-205eeb452366",
            "AppPrincipalId": "",
            "AppSource": 0,
            "AppStatus": 4,
            "AppType": 0,
            "AssetId": "0;00bfea23-e717-4e80-bb17-d0c71b360101;101;",
            "BaseTemplate": 101,
            "ChildCount": 5,
            "ContentMarket": "",
            "CustomSettingsUrl": "",
            "Description": "",
            "IsCorporateCatalogSite": false,
            "LastModified": "4/26/2020 4:16 AM",
            "LastModifiedDate": "2020-04-26T11:16:27Z",
            "ProductId": "00cfea20-e900-4e80-aa17-d0c71b360101",
            "Target": "/sites/mysitecollection/Shared Documents/Forms/AllItems.aspx",
            "Thumbnail": "/_layouts/15/images/ltdl.png?rev=47",
            "Title": "Documents",
            "Version": "4"
          },
          ...
        ]
      }

  • Adding boilerplate code of React component in SPFx using VS Code

    React does not provide command line interface like Angular’s ng generate to create boilerplate code for React components. So you end up copying code from previous components and then modifying it. VS Code has snippets feature that we can leverage to create our own boilerplate code.

    To create your own snippets, go to User Snippets under File > Preferences (Code > Preferences on macOS) and select New Global Snippets file… Enter the name of the snippet file. You get a JSON file with below contents.

    {
    	// Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and 
    	// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope 
    	// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is 
    	// used to trigger the snippet and the body will be expanded and inserted. Possible variables are: 
    	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. 
    	// Placeholders with the same ids are connected.
    	// Example:
    	// "Print to console": {
    	// 	"scope": "javascript,typescript",
    	// 	"prefix": "log",
    	// 	"body": [
    	// 		"console.log('$1');",
    	// 		"$2"
    	// 	],
    	// 	"description": "Log output to console"
    	// }
    }

    Update the file with below code.

    {
    	"SPFx React Component Template": {
    		"prefix": "spfxtsx",
    		"body": [
    			"import * as React from 'react';" ,
    			"export default class $1 extends React.Component<I$1Props, {}> {" ,
    			"    constructor(props: I$1Props, public state: any) {" ,
    			"        super(props);" ,
    			"    }" ,
    			"    public componentDidMount() {" ,
    			"    }" ,
    			"    public render(): React.ReactElement<I$1Props> {" ,
    			"        return(<>" ,
    			"        </>);" ,
    			"    }" ,
    			"}" ,
    			"interface I$1Props {}"
    		],
    		"description": "Creates React component boilerplate code for SPFx"
    	}
    }

    The prefix (spfxtsx) here is the trigger text which will give you option to enter the snippet. $1 indicates tabstop and allows user to enter the name of the component, which is also used in name of props interface. In your tsx file when you start entering spfxtsx, it will populate with boilerplate code.

  • Uploading file with progress indicator in SPFx webpart using PnPJS in SharePoint

    SharePoint provides StartUpload, ContinueUpload and FinishUpload REST APIs to upload large files in chunk. PnPJS Library simplifies the implementation and we have to call only one method to upload file in chunks.

    To upload file in chunks in PnPJS, you call addChunked method by supplying a callback function which can be used to track the progress of the upload.

    sp.web.getFolderByServerRelativeUrl("/sites/naveegator/Shared%20Documents/")
        .files
        .addChunked(file.name, file,
            data => {
                // Here we update the progress by fetching data.blockNumber and data.totalBlocks
            }, true)
        }

    The third parameter in addChunked method is the callback function which provides ability to view in how many chunks the file are being uploaded (totalBlocks) and what is the current chunk (blockNumber) that is being uploaded. Using this information we can create progress bar to show percentage of file uploaded. Below is the React component in SPFx webpart. It uses PorgressIndicator from Office UI Fabric aka Fluent UI to display the progress bar.

    import * as React from 'react';
    import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';
    import { PrimaryButton } from 'office-ui-fabric-react';
    import { sp } from "@pnp/sp/presets/all";
    
    export default class UploadFile extends React.Component<IUploadFileProps, {}> {
      constructor(props: IUploadFileProps, public state: any) {
        super(props);
    
        this.state = {
          showProgress: false,
          progressLabel: "File upload progress",
          progressDescription: "",
          progressPercent: 0
        };
      }
    
      public render(): React.ReactElement<IUploadFileProps> {
        return (
          <>
            <input type="file" id="fileInput" /><br />
            <PrimaryButton text="Upload" onClick={this.uploadFile} /> <br />
            <ProgressIndicator
              label={this.state.progressLabel}
              description={this.state.progressDescription}
              percentComplete={this.state.progressPercent}
              barHeight={5} />
          </>
        );
      }
    
      private uploadFile = () => {
        let input = document.getElementById("fileInput") as HTMLInputElement;
        let file = input.files[0];
        let chunkSize = 40960; // Default chunksize is 10485760. This number was chosen to demonstrate file upload progress
        this.setState({ showProgress: true });
        sp.web.getFolderByServerRelativeUrl("/sites/naveegator/Shared%20Documents/")
          .files
          .addChunked(file.name, file,
            data => {
              let percent = (data.blockNumber / data.totalBlocks);
              this.setState({
                progressPercent: percent,
                progressDescription: `${Math.round(percent * 100)} %`
              });
            }, true,
            chunkSize)
          .then(r => {
            console.log("File uploaded successfully");
            this.setState({
              progressPercent: 1,
              progressDescription: `File upload complete`
            });
          })
          .catch(e => {
            console.log("Error while uploading file");
            console.log(e);
          });
    
      }
    }
    
    interface IUploadFileProps { }
    

    I have used chunkSize as 40960 so that I could display the progress bar for smaller sized file. For actual implementation you can omit that argument.

  • Passing function keys to Windows on Amazon WorkSpaces from MacBook with Touch Bar

    If you have MacBook with Touch Bar and you use it to access Windows on Amazon WorkSpaces then pressing fn + (function key) does not do anything on Windows. To get around this problem you have to update the below settings.

    Go to  > System Preferences… > Keyboard and update the settings Touch bar shows to F1, F2, etc. Keys.

    Downsides to this work around:

    • The function key F11 still goes to Mac and shows Desktop on Mac
    • You lose direct access to App Controls via Touch Bar
  • View all print screen keyboard shortcuts on Mac

    > System Preferences… > Keyboard > Shortcuts > Screenshots

  • A vicious cycle…

    *Submit*

    Your password must be at least 8 characters long.

    *Submit*

    Your password should contain at least one uppercase alphabet.

    *Submit*

    Your password should contain at least one numeric character.

    *Submit*

    Your password should contain at least one special character.

    *Submit*

    Your password cannot contain following special characters @ . / %

    *Submit*

    Your password must not be longer than 12 characters.

    Curses the website, its owner and the software engineer who created it before finally getting through.

    One month later…

    Clicks on Forgot Password?

    *Submit*

    Your password must be at least 8 characters long…

    And the vicious cycle starts all over again!

  • Leap of February

    “Nooooooo!” shouted February. “Why am I being singled out here?”

    “You are not being singled out.” said January, trying to calm February. “August wants an extra day because he is an Emperor. And you know how emperors are, their big fat egos. He wants equal number of days as his adopted father July, if not more.”

    “And you should consider yourself lucky that you didn’t get the fool’s day. Just look at April.” said December.

    February looked at April who was almost in tears. He felt sad for her.

    “But at least I could get 30 days, just like June and November? 28 days is too less.” asked February.

    (more…)

  • I knew IE was bad, but this is unimaginable!

    After finally updating my Windows Vista with Service Pack 2 I decided it was time to upgrade my Internet Explorer from 7 to 9, though I would never be using it. There are times when I feel that I may be criticizing IE too much. So I go to my IE7, search for Internet Explorer 9 and go to its download link. And this is what I get.

    Yes IE7 cannot even properly open the download site for IE9. I mean I knew IE was bad but this is unimaginable!

    Image credits: The screenshot of error belongs to me. If you want to get this picture I would recommend you installing IE7 and going to download site for IE9. Good luck!

  • Updating my Windows Vista

    I was recently updating my Windows Vista (yes I still use Windows Vista, don’t ask why) and this is how it went.

    Downloading 231 MB of updates — 1 hour

    Installing Updates — 3 hours, yes THREE hours

    (more…)

  • If software engineers made movies

    If software engineers made movies they would be called with a slightly different name —

    ♦ Jo Jeeta Wohi Sikandar → Race condition

    ♦ Ghajini → Memory leak

    ♦ Chakravyuh → Recursion

    (more…)