Monday, April 9, 2018

Upgrading SPFx React from 1.1.0 to 1.4.0 build errors

Hey guys,

I've been playing with my SPFx demo project (code here on GitHub) getting ready for my session @SPSTC when I decided perhaps its time to upgrade one of my demo web parts to SPFx version 1.4.0 while keeping the other one in 1.1.0 so that I can discuss the upgrade process.

The upgrade process is, as I stated many times, a very tedious and hard manual work - and VERY error prone and time consuming.

Here are a few notes I gathered from this upgrade that I'd like to share - join my session to get the full picture!

Following this article as my base-line: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/toolchain/update-latest-packages
There are a few things that went wrong here...

React versions

If you follow this guide, it says to run npm outdated and get all packages to the latest versions. Well, that simply is bad advice since when it comes to the react packaged - you should get the same version that the Microsoft packages are using. This is not explained anywhere - you just end up with hundreds of errors in your gulp command with no clue why they are there or how to fix them. I simply went into the Microsoft packages and saw they were using these versions so I used the same:
  • "@types/react": "15.6.6"
  • "@types/react-dom": "15.5.6"
  • "react": "15.6.2"
  • "react-dom": "15.6.2"
That brought down the errors count to 1. Sounds simple? Not so much...

React createComponent error

See, in my web part demo that was built on version 1.1.0 of SPFx - the react component class was declared as:
export default class ReactWebPart extends React.Component<IReactWebPartProps, void>
In the web part class, it was used in this code:
      const element: React.ReactElement<IReactWebPartProps> = React.createElement<IReactWebPartProps>(
        ReactWebPart,
        {
          description: this.properties.description,
          userName: Utilities.GetUserName(this.context as any),
          license: licenseMessage,
          color: this.properties.color
        }
      );
which, in turn, produced this error message:
Error - typescript - src/webparts/reactWebPart/ReactWebPartWebPart.ts(27,8): error TS2345: Argument of type 'typeof ReactWebPart' is not assignable to parameter of type 'string | ComponentClass<IReactWebPartProps> | StatelessComponent<IReactWebPartProps>'.
Error - 'typescript' sub task errored after 4.49 s
 TypeScript error(s) occurred.
So, we checked the typescript version we were running, all the npm modules dependencies and versions - they all seemed to check out.
We went with our favorite way for fixing SPFx versioning issues:
We created a new sample SPFx React web part, and if that one (hopefully) compiles - we compare the two.

In our case, since this is a sample component without a lot of code - it was easier to find the difference between the two.
In the new project, the react component class is defined with one difference:
export default class ReactWebPart extends React.Component<IReactWebPartProps, {}>
See, the "void" that was sent in as the react state was changed to an empty object.

This made the error go away and now our project compiles with no problem. Yay!

I can't help but feeling SPFx tooling still has a long way to go before it will be adopted by the mass development community. It can get pretty frustrating every time you have to move computers or upgrade versions to the point that it is just scary and unpredictable.

That said - I have to admit it is brilliant, fast and fun to build on when you get it to compile. So - I'm keeping my hopes up for this platform.

I will continue to provide this feedback to the team @Microsoft, which are doing a great job at listening for feedback, but please also share your experience in the comments below, on their GitHub project  or by voting on user voice requests.

Here is a link to the GitHub with this project in case you want to see the code changes during the upgrade: https://github.com/KWizCom/SPFxDemo

Hope this helps,
Shai.
Funny thing... not 5 minutes after posting this, I went back to my demo and run gulp. Guess what? It errored out. This time showing this strange error:
[17:53:08] Error - Unknown
 Cannot find module 'typescript'
Guess what worked this time to fix this? delete node_modules folder and running npm install again...

Wednesday, March 28, 2018

Transforming SharePoint radio buttons to appear horizontal

Recently I was at SharePoint Saturday DC.
While I was at KWizCom's booth, one of our customers approached me with a question: He had a list form with lots of radio buttons.
They each had just a few choices, but the form didn't look very nice since they all stretched out too long and narrow.
See, SharePoint always renders radio button choice fields vertically...

He wanted to have these choice columns render in a horizontal layout instead of the OOB vertical one. (side by side instead of under each other)

In other words, from something that looks very much like this:
Into something that looks like this:

(Due to privacy of his content, I can't share his exact form layout - but he had a few more of them spread around the form)

So, you might notice the customer was already using our forms solution and had the form render in a 2 column layout and with the column captions above the controls.

Because of that, the change he requested was very simple to implement so I was happy to do it on the spot with him, on his laptop.

It took about 2 minutes to complete, he was very impressed, but I must admit - this wasn't a very challenging request if you know your way around CSS.

All he had to do was:
1. Create a CSS file with a new class that targets the table in radio buttons choice columns
2. Change the rows of the table to display inline instead of breaking row like it usually does in HTML
2. Save the CSS file in site assets
3. Get our Forms solution to load this new CSS file and all done!

Here is the CSS needed to make this change, it should work on SP2013, SP2016 and SharePoint online in classic UI:

table[id$='RadioTable'] tr{ display: inline; }

Note: if you don't use KWizCom Forms, you will have to load the CSS some other way to the page, but this solution should still work.

Note #2: this wasn't tested on modern UI, but on classic. It might require some minor tweaking to work in modern UI, let me know in the comments if this is something you need and having trouble achieving.

Enjoy!

Friday, March 9, 2018

Recent breaking changes in SharePoint Online

If you ever wondered why SharePoint online apps/add-ins/products are sold almost exclusively as subscription - here is your answer.

We at KWizCom run full automated testing on several production tenants as well as on our own fast-ring release tenant every night, as well as after every build is pushed to fast ring or to production.

More often than we'd like, we see glitches or breaking changes pushed to production that make some or all of our code stop working as intended.

Here are a couple of stories from the past 48 hours:

First


Product manager sets up a live demo of our forms solution. EVERY THING breaks. Pages load with no settings, after a refresh - with only some settings and on other times normally with everything working.

We investigate and notice that SPO (SharePoint Online) is returning a JS file we store under the site assets with a different content every time.

We cancel all caching, open the file in the browser - and you won't believe it! We get a different file every time!

We rename the file, so the file in that URL doesn't exist anymore. Is the problem gone? No - it's worst. Now it comes back in 3 different versions as well as a 404 not found error occasionally.

I'm freaking out, calling on all my Microsoft contacts to investigate. Within 6 hours the problem is gone like it never happens.

Was I dreaming? NO! I got the video to prove it:



Now, obviously I can't reproduce it so I can't give Microsoft additional information, there is no way to know what happened and how to prevent it from happening again.

(Sounds to me, like a new caching feature was being tested out and pushed to production, then later pulled back).

Second

You thought the first story was strange? try this one. We have a provider hosted app that customers are required to install in order to get our products working.
We literally had this app for YEARS with no problems.
Two days ago we get a support call that no one can install our provider hosted app.
We check and see that our app has an install and uninstall remote event receivers - and that event receiver is throwing error 500.

This event receiver code hasn't changed in years, so what happened?
Well, a built in method that visual studio project auto-generated for us that gets the clientContext used to work, or return null if the app was not trusted.
In the last 48 hours it now stopped working and was throwing an exception blowing up our event handler.


Fun times.
In the first case, we had nothing to do but wait, in the second - it was a simply easy fix. But you get my point as to why we need to constantly monitor and push updates for our products?

Now, you might better understand why I am a strong advocate of allowing vendors to update apps remotely without forcing each user to install a new package (like they try to make us do in the new SPFx eco-system).

We literally push hundreds of updates and fixes every month for all our products without bothering the users to install them - I can't imagine we would have happy customers if they would need to install hundreds of updated packages every month...

Now, if you are wondering why we need so many updates, and boasting about your single app that was built X years ago and working until today - ask yourself what does it do. My guess: not much more than saying "hello" or showing the current time and weather... ;)

Hope this provides some insight to those who are looking to support SPO or any cloud service in their products. Sound off in the comments if you have more to add!