Wednesday, 23 November 2022
Building a custom Microsoft Teams tab: Show a native loading indicator
Monday, 1 November 2021
Working with MSAL and multiple Azure AD accounts in a React SPA
I came across an interesting scenario recently: I was working with a React SPA which used Azure AD for authenticating users, and it needed to work with multiple accounts logged in simultaneously. Specifically, we were building an Azure AD multi tenant application which needed to login to multiple M365 and Azure tenants and allow the user to manage all tenants at the same time.
The good thing was that MSAL v2 does support working with multiple accounts at the same time. So in this post, let's see how we are able to do that in a React SPA with MSAL js.
Before looking at the code, we would need to create a multi tenant Azure AD app which would be used to sign in to the different tenants. Step by step instructions can be found here: https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-javascript-spa#register-your-application
The very first thing we would need is to setup the configuration for our app:
Tuesday, 26 May 2020
Create a custom React hook to mimic class component's setState behaviour
This post generated some good discussion on twitter with Yannick Plenevaux regarding the ideal cases when to use this approach as opposed to other approaches of state management like using the useState or useReducer hooks. Have a look here: https://twitter.com/yp_code/status/1265244244077416448
Monday, 27 April 2020
SPFx Teams tab: Use react hooks to dynamically handle theme changes
Also, if the user switches the theme (e.g. from default to dark), we want to make sure that the styling of our SPFx web part also changes without the user having to reload the tab.
Let's see how we can do this. In this post, depending on the Teams theme, we will dynamically add a CSS class to our top level react component. And when the theme changes, we will change this class as well. That will be the scope of this post without going into further details of Styling/CSS.
Also, since I have been exploring React hooks recently, we will be using them in the demo code.
The very first thing we need to do is to make sure that our SPFx tab loads with the currently selected theme when the tab loads for the first time.. This can be achieved with the teamsJS sdk bundled with SPFx:
The theme property will either have the values "default", "dark" or "contrast" (at the time of writing this post). Depending on this property, we can add a CSS class to the top level container of our web part.
Now the important part. When the user updates the theme, we want to fire an event which can be used to set the new theme in our tab. Luckily the teamsJS sdk provides us with a function which can be used to register this event handler:
https://docs.microsoft.com/en-us/microsoftteams/platform/tabs/how-to/access-teams-context#theme-change-handling
With this, we are able to capture the theme update dynamically and update our component state. Next, we also want to change the CSS class of the top container when the theme changes. We will do this by using the useEffect hook again and setting the class depending on the selected theme.
This hook takes in the themeState as a dependency which means that it will run anytime themeState changes. We will use it to update the styleState.
I could have been a bit more clever here and simply updated the class in the registerOnThemeChangeHandler function itself. But I wanted to keep the themeState and styleState separate to have them loosely coupled and also to play around with hooks a bit more ;)
Here is the complete code for the React Functional component:
Hope you found the post useful! As always, the code for this post is available on GitHub: https://github.com/vman/spfx-teams-theme-hooks
Wednesday, 5 February 2020
SPFx: Using React hooks to globally share service scope between components
For example, without using service scopes, if we wanted to make a call to the Microsoft Graph (using MSGraphClient) from within a deeply nested react component, either we would have to pass in the SPFx context down all the components in the tree, or maybe a create a custom service which returns the web part context, and then call that service from within our nested component. Or maybe use redux to globally maintain the context in a single state object.
But with all these approaches (there may be more), testing the components would be difficult as they would have a dependency on the SPFx context which is hard to mock. Waldek Mastykarz has a great post on this.
Also, from a maintenance point of view, it could get tricky as almost all our components would start to depend on the entire context and we could easily loose track of which specific service from the context is needed by the component.
Now with my previous posts on service scopes, even though we were removing the dependency on the SPFx context, one issue still remained that the SPFx service scope was still needed to be passed into the component. We were just replacing the SPFx context with the SPFx service scopes. While this was good from a testing point of view, it wasn't great for maintainability.
Fortunately, in the recent versions of SPFx, React 16.8+ was supported which means that we can take advantage of React hooks. Specifically, the useContext hook. This gives us a very straightforward way to store the SPFx service scope in the global react context (which is different to the SPFx context) and then consume it from any component in our application no matter how deeply nested it is.
Let's see how to achieve this. In these code samples, I am using SPFx v1.10 which is the latest version at the time of writing.
1) The Application Context object
First, we need to create the React application context object which will be used to store and consume the service scope. For now I am only storing the serviceScope in the context. Other values can be stored here as well.
2) React Higher Order Component (HOC)
React hooks can only be used from functional components and not classes. With the SPFx generator creating classes by default and hooks being fairly new, I am sure there is a lot of code out there already which use classes and not functional components. Changing all code to use functional components instead of classes is a non-starter.
Fortunately, there is a way to use react hooks with classes by creating a Higher Order Component (HOC) which is a functional component. We can wrap all our class components with this HOC and safely consume the useContext hook from within this component.
(Update: If you are interested in going down the "full hooks" approach and doing away entirely with classes, Garry Trinder has got you covered. He has created a fork which only uses functional components and hooks so we don't need the HOC. If you want to take this approach, check out the code here: https://github.com/garrytrinder/spfx-servicescopes-hooks)
3) SPFx web part
Next, we update our SPFx webpart to only pass in the serviceScope once to our top level component:
4) Top level React component
Our top level component will need to be wrapped with the AppContext so that any nested component will be able to consume it. This just needs to be done once on the top level react component. You will notice that the HelloUser child component does not need any props passed in.
5) Child component
Due to the Higher Order component and the useContext hook, we are able to access the serviceScope property from withing the child component. We can grab the MSGraphClient from the serviceScope and start making calls to the Graph:
And that's it! This way, we can use the React useContext hook to globally share our SPFx service scope.
Hopefully you have found this post helpful! All code is added in the GitHub repo here: https://github.com/vman/spfx-servicescopes-hooks
Also, if you are interested, here are all my previous articles on SPFx service scopes:
SharePoint Framework: Org Chart web part using Office UI Fabric, React, OData batching and Service scopes
Getting the current context (SPHttpClient, PageContext) in a SharePoint Framework Service
Service Locator pattern in SPFx: Using Service Scopes
Service Locator pattern in SPFx: Using nested scopes to work with multiple components
Monday, 2 September 2019
Create SPFx Library components containing Office UI Fabric React
Let's see how to achieve this. We will be working with SPFx 1.9.1 which contains the GA version of Library Components:
1) Create SPFx Library and Consumer component structure
First, make sure you have an SPFx library project as well as a "consumer" SPFx project containing webparts (or extensions). Instructions on how to create this are in the Microsoft docs: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/library-component-tutorial
The code for this post is also available on GitHub if you want to have a look: https://github.com/vman/spfx-lib-components-ouifr
2) Create a new custom react component which internally uses Office UI Fabric React
3) Update the index.ts file
In the index.ts file of the library component, include the new component to be exported:
4) Update config.json
Next, in the config/config.json file of the library component, make sure that the entry point is pointing to /lib/index.js
5) Update the consumer web part
Make sure that the library component is referenced in the consumer webpart e.g. through npm link or by using a monorepo manager like rush or lerna.
More details on using npm link in this in the Microsoft docs: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/library-component-tutorial
Monday, 8 October 2018
Code Splitting in SharePoint Framework (SPFx)
E.g. when a React component or a third party package is only needed when the user clicks on a certain button, then there is no need to load in on the first page load. It can be fetched on-demand when the button is pressed. This reduces the amount of data fetched over the wire on first page load, thus improving performance and user experience. This can be particularly helpful in large applications with many third party packages and components.
In this post let's have a look at how to do code splitting in the SharePoint Framework. As an example, I am going to use an SPFx web part created using React but the code splitting approach can be used with other frameworks/libraries as well.
We are going to have a look at two scenarios where code splitting can really help:
1) Loading a React Component on-demand (where we load the DetailsList component from Office UI Fabric)
2) Loading a third party package on-demand (where we load the infamous-for-its-large-size moment js)
So to begin with, here is my render method of a React component created by default by the SPFx yeoman generator:
I have edited it to show only 2 buttons. This component will be our "main" component which will load other components and third party packages when a user clicks on the relevant button.
Load a React Component on-demand:
The _loadDocumentsClicked function will fire when the user clicks on the Load Documents button. The DetailsList component is defined in a file called DetailsListComponent.tsx which is in the same folder as the main component.
Once the import function fetches the DetailsList component class, we create an an instance of the class and use ReactDom to insert the component to the detailsContainer div in our main component.
Load a third party package (moment js) on-demand:
Similarly, the _loadMomentClicked function will fire when the load moment js button is clicked. it will fetch the moment package and then assign the value of moment().calendar() to a property in the current component's state.
And here is the code in action on a modern SharePoint page:
What is also important to note is that the bundle will be loaded only if it was not loaded earlier. The import function is smart enough to determine if the bundle is already downloaded and it does not request it again.
Hope you found this useful!
As always, the code for this is available on GitHub: https://github.com/vman/SPFxCodeSplitting
Thursday, 13 July 2017
Using Redux Async Actions and ImmutableJS in SharePoint Framework
While working on it, I came across libraries like Redux and ImmutableJS and how they help solve particular problems in React and the modern JS world. This really peaked my interest, so naturally, like all new things I learn, I tried to see how they could be applied to SharePoint. So in this post, lets have a look at what problems do Redux and ImmutableJS solve and how we can use them in a SharePoint Framework web part:
Source of this web part is available as a part of Microsoft's SharePoint Framework client-side web part samples & tutorials on GitHub: https://github.com/SharePoint/sp-dev-fx-webparts/tree/master/samples/react-redux-async-immutablejs
Why Redux?
I am going to assume that you are familiar with React and understand the basic concepts. If not, have a look at the tutorials on the react website, they are really great to get you started.
So as you know, the way React components work is every component displays it's UI based on the component's state. When the state is updated, the UI of the component is updated as well.
Since I was working with multiple components, I quickly realised that some events in my application would mean updating the state of more than one component. How do we make this happen? The easy (but not so great) solution was to move the state in the parent component of the two child components and then pass the state as properties to the child components. If we wanted to update the state from a child component, we would update it using a function (which is also passed as a property to the child component). When the state in the parent component was updated, it would automatically update all the child components as well.
This would quickly become tedious as more components are added to the application. The state will have to be passed down deeper and deeper in the component tree which is not really ideal.
Luckily, there is a nice solution to this problem with the introduction of Redux. With Redux, what we do is maintain the entire state of our application in a single object. This state is connected to our components and is passed as properties to them. Any change to the state is defined with an Action which is dispatched when an event occurs.The Reducer receives the Action and updates the necessary elements of the state. (Which in turn updates the UI of the relevant component)
This is the general idea of Redux. If you want to have a deeper look and also check out some advanced concepts, there are some excellent tutorials here: http://redux.js.org/
Working of the SharePoint Framework webpart:
When the page loads, a redux action is fired which makes a REST API call using SPHttpClient to the current site and gets all the lists. Once the lists are fetched, another redux action is fired to instruct that all lists were successfully fetched from the server. The reducer listens for these actions and updates the state (UI) accordingly.
We can also create a new list from the webpart. When the user enters a value in the text box, an action is dispatched which updates the element in the state which represents the new list title. When the user clicks on the "Add" button, an action is dispatched which again makes an async call using SPHttpClient to create the list. Once the call is successfully returned, the UI is updated with the name of the new list.
Redux Async Actions:
Each async operation ideally has 3 actions to go along. This is not a requirement but is helpful to nicely manage our UI when the operating in being performed. We will see why we need 3 actions for one operation in the Reducers sections below. For now, all we need is a "request" action which we will fire before making the async call, a "success" action which we will fire after the aync call returns successfully and then an "error" action which will be fired if the async call returns an error. Here are the 3 actions we will use in our webpart, and then a parent action to wrap them all together:
Reducers:
A reducer determines how the state should change after an action occurs. For example, when a "request" async action is triggered the reducer changes the application state to show a loading icon. When a request is successfully completed and it returns data from the server, the "success" action is triggered and the reducer determines that the loading icon should disappear and the data should be shown instead. Similarly, if an error would be returned from the server, the "error" action would be triggered and the reducer should show an error message on the screen instead of the loading icon. Here is our reducer code which modifies the sate using ImmutableJS. In this code, to keep things simple, we are only updating the state when the success action is dispatched. We are not showing or hiding a loading icon here.
When a reducer updates the state, a core principle of react is that we should never mutate the state object. We should always make a copy of the state, update the necessary elements in the copy and then return the copy as the new state. More details on why immutability is important here: https://facebook.github.io/react/tutorial/tutorial.html#why-immutability-is-important
ImmutableJS:
Let me begin by saying that using Immutable JS with Redux is not mandatory. We can use native ES6 features like Object.assign or the spread operator to create a new copy of the state, update the necessary elements and return the new copy. (Just remember that for supporting IE, we will need polyfills for these) If we have small to medium sized application, this is perfectly fine.
But if we are maintaining lots of elements in our state, making a new copy of state for every action can be really performance intensive. For changing only a single element, we have to copy the entire state tree in memory, and that too for every action. Fortunately, ImmutableJS comes to the rescue here.
Using ImmutableJS, we can create a new state object in memory without duplicating the elements which are unchanged. When we create a new state object using ImmutableJS, the new object still points to the previous memory locations of unchanged elements. Only the elements which are changed are allocated new memory locations. The new copy of the state points to the same memory locations as the old copy for unchanged elements and it points to the new memory locations for the changed elements.
Here is our application state which extends the Immutable.Record class:
We have used TypeScript readonly properties in the state to mandate that these properties should never be updated directly. Instead, the custom "setter" functions should be used. In the setter functions, we use ImmutableJS methods such as "set" and "update". These functions take care of returning a new copy of the state where the only the changed elements are stored in new memory locations.
Hope you have enjoyed reading this post.
Check out the full code of the web part here: https://github.com/SharePoint/sp-dev-fx-webparts/tree/master/samples/react-redux-async-immutablejs
Tuesday, 13 September 2016
SharePoint Framework: Org Chart web part using Office UI Fabric, React, OData batching and Service scopes
Code is available on GitHub as part of the SharePoint Framework client-side web part samples & tutorials: https://github.com/SharePoint/sp-dev-fx-webparts/tree/master/samples/react-organisationchart
1) For getting the Manager and the Reports of the current user, the ExtendedManagers and DirectReports user profile properties are used.
2) Uses the OrgChart CSS directly from the Office UI Fabric: http://dev.office.com/fabric/OrgChart (Not the Office UI Fabric React components which are still in progress)
The Office UI Fabric CSS is bundled together with the web part and not referenced externally. In the OrganisationChart.module.scss:
Thanks to my colleague and buddy Paul Ryan for this tip.
3) The REST API calls are made with the HttpClient belonging to the current ServiceScope. No need to pass web part properties or the web part context.
4) The Managers and DirectReports are fetched by registering a mapping of the UserProfileService class in the current ServiceScope
5) OData Batching is used to get details (Photos, Titles, Profile Urls) of all DirectReports in a single call. (Similarly, if more than one Manager exists in the ExtentedManagers property, details of all users are fetched in a single batch call)
More on OData Batching in my previous post: Batch REST requests in SPFx using the ODataBatch preview
Hope you find this useful!









