The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
DrewW
Mega Sage
Mega Sage

So we are looking at implementing Customer Service Management and there are some things that we need to display to the user and ServiceNow's new UI Framework was/is looking like the way to go about it.  Unfortunately this is ServiceNow's first pass at and there appears to be a lot of things still missing.  So I decided to write this in the hope that it would help someone start a little ahead of where I did.  So if you have answers to any issues that I have not solved yet please post a comment, conversation is always good.

Lets start with some documentation to read.  The Developer site has a number of things that are vary useful but if you are looking for a step by step to show you how to do your first one then you need to start with the docs site, which was the first mistake I made was reading thru all of the Developer docs and then trying to create something.  So I would read both and read up on Web Components since its all sitting on top of that..

https://docs.servicenow.com/bundle/orlando-servicenow-platform/page/build/components/concept/custom-...

https://developer.servicenow.com/dev.do#!/guide/orlando/now-experience/cli/getting-started

After that you can spend some time looking over some of the stuff that Brad Tilton posted on his blog.  He has some good links to review and Andrew Pishchulin has some good stuff to look over

https://developer.servicenow.com/blog.do?p=/post/orlando-components-lchh-recap/

https://medium.com/@pishchulin/servicenow-ui-framework-be88f466be01

So the last link I would like to give out is one about ES6.  Its been a long time since I have done any coding outside of ServiceNow so when I started looking at the examples there was some code that I looked at and went "Hu what?" so I need to do some reading on that to understand the examples.  So while talking with my friend Tony about this, he sent me a link that helped explain some things so I'm supplying it here as I'm sure it will help others who are not ES6 experts like me.
https://www.sitepoint.com/es6-enhanced-object-literals/

So on to what I did and some thoughts on it but if you go thru the stuff above I'm not sure you will get much from the below but you never know.

 

So I started with a basic component that would have a sub component which in turn would have another sub component.  The basic structure is that I have an AIG, under that I have a section and under that I have a subsection and finally I have data.  To start with I created a file with some data in it for testing.  Below is a sample of the data in my data.js file.

export const aigs = [
    {
        name: "AIG 1",
        sections: [
            {
                name: "section 1",
                subsections: [
                    {
                        name: "subsection 1",
                        data: [
                            {
                                type: "dropdown",
                                value: "dd1",
                                displayvalue: "dvdd1"
                            }
                        ]
                    },
                    {
                        name: "subsection 2",
                        data: [
                            {
                                type: "text",
                                value: "txt1",
                                displayvalue: "dvtxt1"
                            }
                        ]
                    },
                    {
                        name: "subsection 3",
                        data: [
                            {
                                type: "multipick",
                                value: "mp",
                                displayvalue: "dvmp1"
                            }
                        ]
                    },
                    {
                        name: "subsection 4",
                        data: [
                            {
                                type: "dropdown",
                                value: "dd2",
                                displayvalue: "dvdd2"
                            }
                        ]
                    }
                ],
            },
            ...
        ]
    }
 ];

 

Created the directory for the project, it has to be empty so you cannot just create one in a directory with another.  Logged in to our dev instance and did a now-cli project to get it built.  First thing I found was that I could not do a now-cli develop and this is when I found that the Developer docs was missing something that the Docs site had.  Once you have your project created you need to do an npm install and that will get you all of your dependence's so you can do a now-cli develop and test your component locally.

So once I got past that putting in some HTML was simple enough.  Then I tried an image.  I new I needed to make some settings changes to the proxy information so it would get my image from the instance when I run.  But I struggled to get it to work until I found one of Brad's links to Dylan Lindgren's page where he indicates you need to add the file name to the proxy settings but what I found is that you can get away with /*.jpg and it will get all jpegs from the instance you are using. So you can set the proxies line to the following

"proxies": ["/api", "/amb", "/*.jpg", "/*.png"]

So basically this will tell the local web server to send the api, amb and any call that ends with jpg or png to the instance for fulfillment.  The last item I discovered is that if you need to change the now-cli.json file that for the changes to take affect you need to cancel the now-cli develop command with ctrl+c and run it again.  If anyone knows a way to get it to refresh on the file I would love to know, I could not find one.

Ok so now I have a picture so lets get some data from a file and display it, I will deal with getting it from the instance later.  So I built this code and tried to understand the formatting that I had not seen before.  Been working in the ServiceNow server side bucket a little to long I think.

find_real_file.png

So line 5 is where we get the data, first thing I was doing was why do I need {} around it.  The answer is Destructuring which I learned about from the ES6 link I provided above.  Basically its a short hand for creating an object, developers always like to type less.

Next item I was looking at was line 7, again ES6 link above to the rescue.  This is again developers showing there desire to not type and is a short hand for declaring a function but it also lacks bindings to this and others, see this link.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Ok so that all seams simple enough once you understand it so on to my sub-component, and this is where I thank Chuck and the other crew of the Live Codeing Happy Hour as they went thru and created one.  Basically its not that difficult. You create a sub folder in the src fold in your workspace in VS Code and then import the component. 

find_real_file.png

Ultimately you are doing this just for code management.  You could just put everything in one big file if you wanted to but the people who work on this after you may curse your name.  So once the folder is created you just put an index.js and styles.scss files in there as needed.  Then you need to import it into your first component and that is what line 4 is for in the code above.

So my second component looks like this
find_real_file.png

So now this is were I started to have a few more struggles with things that I did not realize right away.  First one is that what your view returns on line 8 in the above code has to be wrapped in a single tag, it cannot be more than one.  So this does not work

const view = ({properties: {sections}}) => {
	console.log(sections);
	return (
		<div>{section.name}</div>
		<mahe2-bok-aig-subsection subsections={section.subsections}></mahe2-bok-aig-subsection>
	);
};

You will get a compile error when you try and do a now-cli develop or save it if already running.

My third component was basically the same as the second one but there needed to be a loop in a loop which is strait forward enough.

const view = ({properties: {subsections}}) => {
	return (
		<div>
			{subsections.map(subsection => (
				<div>
					<div className="indentSome">{subsection.name}</div>
					{subsection.data.map(data => (
						<div className="indentSomemore">{data.displayvalue}</div>
					))}
				</div>
			))}
		</div>
	);
};

Again everything in the loop has to all be contained in a single tag. 

Also one of the things that confused me for a while was this line of code

const view = ({properties: {subsections}}) => {

What exactly am I passing into my function?  The properties object or the subsections object?  Both or something else?  But I finally realized that this is a type of Destructuring.  Basically what its telling you is that you are passing in the properties.subsections object and it will be called subsections.  Its possible to rename the variable to something shorter by doing this

const view = ({properties: {subsections: secs}}) => {

So basically the properties.subsections object will be assigned to a variable called secs that you can use in your code.  The ES6 link at the top talks about this.  Leave it to us developers to come up with something that takes less typing and provides less readability.  🙂

My next thing to do is to get data from the instance and this is where I have more questions and need to do more reading.

So my first question is when I put this on a workspace how do I know what record I'm looking at so I know what data I need to load or how my data is linked to the record the user is looking at?

What OOB styles are available and were is the docs for it?  Bootstrap does not appear to be available so I need to reinvent the wheel for layout?

How often is the view function called?  When ever the browser see's a change in the data?

Is it better to make my data calls in the view function or do it after the system attaches the component to the page?  My concern is that if the view function is called a lot and I make a REST call each time thats going to be slow when I may not need to get the data more than once.

Is it possible to pull down the code for a component?  I suspect not so better get a Source Control option in place or I may end up having an awkward conversation with my boss about how I lost weeks worth of work. 

If you have any answers to questions, have questions yourself or just feel like commenting please do.

Comments
Tommy Jensen
Mega Guru

So now this is were I started to have a few more struggles with things that I did not realize right away.  First one is that what your view returns on line 8 in the above code has to be wrapped in a single tag, it cannot be more than one.  So this does not work

 

I don't know if you have figured this out yet. If you have more than one top node then you have to specify it as an array. 

I watched a course about Web Components. One on Udemy by Maximilian Schwarzmüller

So your example formatted like this should work (I have not tried it, this is just from the theory learned from the course 😉 )

return ([
		<div>{section.name}</div>,
		<mahe2-bok-aig-subsection subsections={section.subsections}></mahe2-bok-aig-subsection>
	]);

yes a bit weird. 

DrewW
Mega Sage
Mega Sage

You get an error when you save it an Node.js "compiles" it.  I believe it has to do with how JSX works but do not know for sure.

 

Tommy Jensen
Mega Guru

That is strange you get errors.

 

I have just tried following and it works fine, no errors. This is in a complete oob project made with the now-cli.

const view = (state, { updateState }) => {
	return ([
		<div>
			<h1>Test2 </h1>
		</div>,
		<div>
			<h1>Test3 </h1>
		</div>,

	]);
};
DrewW
Mega Sage
Mega Sage

That is because you used an array, the code sample that I did does not set it up as an array.  Its a subtle difference but important.  So with JSX you have to have one containing element for the HTML.  Which in your example you do for each element of the array.  If you did the following it would not work because the second array element is not wrapped in one tag, which is easily fixed by simply adding a comma.

const view = (state, { updateState }) => {
	return ([
		<div>
			<h1>Test2 </h1>
		</div>,
		<div>
			<h1>Test3 </h1>
		</div>
		<div>
			<h1>Test4 </h1>
		</div>
	]);
};

 

Tommy Jensen
Mega Guru

I know that. That is how the Web Component standard works. If you need more than one element at the top level you must specify them in an array.

Tommy Jensen
Mega Guru

An alternative is to use Fragment like this:

return (
		<Fragment>
			<div><h1>testing</h1></div>
			<div><h1>test sysId: {properties.sysId} - table: {properties.table}</h1></div>
			<example-checklist></example-checklist>
		</Fragment>

	);
DrewW
Mega Sage
Mega Sage

Did you get that code to work?  When I tried it I got "Fragment is not defined".  If you have to include something to use it I'm not sure its worth the effort to use when you can just return an array and not bother with it.

 

 

Tommy Jensen
Mega Guru

Yes it works but you have to remember to import it.

import snabbdom, { Fragment } from '@servicenow/ui-renderer-snabbdom';
DrewW
Mega Sage
Mega Sage

Ok, so while good to know were it is if you do want to use it I'm not sure it really has much use.  React has it so you could can return say a bunch of td or say li tags, but you can just return an array of elements that it will render and that gets you the same thing with out having to use a special tag for it.

Tommy Jensen
Mega Guru

I will use it for two reasons:

1. It appears to be a sort of best practice ServiceNow would like us to use: https://developer.servicenow.com/dev.do#!/guide/orlando/now-experience/dev/writing-html

2: The array syntax once setup it is so easy to forget that comma at the end if adding a new div. 

DrewW
Mega Sage
Mega Sage

Based on what they say on that page they are just giving you an option if you cannot add a parent tag like in the case of needing to return TD tags, but I would not call it a best practice. The rest of it I guess comes down to coding choice.

Rohant Joshi1
Tera Contributor

This is amazing.

I am very impressed with this new feature of servicenow do not know what id future for this, but after reading https://medium.com/@pishchulin/servicenow-ui-framework-be88f466be01 looks like there is a lot we can do.

I was just wondering if you guys thoght about introduing external dependencies in the component that you are building. 

Like can we introduce bootstrap in the indes.js file or is there any other approach to inject some external CSS libraries.

Tommy Jensen
Mega Guru

In theory you should be able to use ANY npm.js package. 

Like this calendar https://community.servicenow.com/community?id=community_article&sys_id=458c426d1b9c9010d01143f6fe4bc...

 

I am currently trying a different calendar that my colleague have used in Service Portal so to have a unified look I want to use the same but have not gotten it to work yet. I am almost certain it is just me not doing it right so still have some work to do on that.

DrewW
Mega Sage
Mega Sage

This is what I did to use bootstrap in a component I was testing out.

npm install bootstrap
npm install jquery
npm install popper.js

 

In CSS file
@import '../../node_modules/bootstrap/dist/css/bootstrap.min.css';

In js file
import 'bootstrap';

After that I was able to use all of the bootstrap stuff.  It included everything in the component when I pushed it to the instance, which of course makes the component bigger.  Its not clear thou if you use bootstrap in say 10 components and they all load on the page if the system is going to have 10 instances of bootstrap loaded into memory or just one.

 

DirkRedeker
Mega Sage

Hi

When uploading a "compiled" component to the ServiceNow Instance, the "source code" for it will not be uploaded. 

Knowing that, it will not be possible to "download" the source code for any component from the ServiceNow Instance (yet). So, your proposal or idea is correct, to create some repository (like on GitHub) for you to share the code. Also make sure, to make separate backups of your code, as you can not get this back from your ServiceNow Instance.

Publishing is a one-way process.

BR

Dirk

DirkRedeker
Mega Sage

Hi

One thing, that I was wondering first was, how does the local development component access data on the ServiceNow instance?

All of the component development will be done locally on your machine and all source files will only be stored on your local drive.

NOTE: Do NOT story the source code on any Cloud-based folders, like "OneDrive" or "Dropbox" Mirrors etc. This may lead to unexpected results. Better use any local "plain vanilla" folder for development.

NOTE: Some say, you should execute the "NOW-CLI" in Admin Mode of the "CMD.EXE" on a Windows box. I did not experience this to be true, but I would like to know about your experience.

 

When "executing" a component locally with "now-cli develop", a local web-server will be lauched, which will have the component to be shown in your browser. This Web-Server utilizes a local Proxy, which connects to your ServiceNow Instance (which you connected to with "now-cli login ..."), and this way, the access to local functions in your instance is transparent. 

This in fact is a very cool feature to give full local experience for your development.

BR

Dirk

Tommy Jensen
Mega Guru

Yes I LIKE Now Experience 🙂

I have not had any permission issues on my windows 10 pro. I just open Visual Studio code normally and then open a terminal window inside Code and run the now-cli command there.

DrewW
Mega Sage
Mega Sage

Just wait until you start needing some of the information from the record the user is looking at.  You cannot get that in the local dev environment.  You have to start deploying it to the instance for testing.  I like the fact that it allows customization of the UI but ServiceNow has a really long way to go in there documentation.

One major item I would like to see ServiceNow do is when you deploy a component it will deploy both the version it does now and also a version that is the local project so if something happens you can pull down that version to your local system and continue to work on it.

 

DirkRedeker
Mega Sage

Hi Drew

In fact, this is the COOL thing! 

The Proxy really makes you "feel working in the instance".

All the HTTPEffect Calls are done locally on your machine, but the data I fetched via the Proxy from the Server. That is awesome!

Do you need some support on that?

BR

Dirk

DrewW
Mega Sage
Mega Sage

This was my first component and the things I ran into, so no.  I have since done a number of things and find the components useful but Service Portal widgets I find way easier to deal with when it comes to testing and trouble shooting.  They also have less risk when it comes to loosing changes and or the original code because its all stored in the instance.

I do like that we can do completely custom things.

Tommy Jensen
Mega Guru

There is no question developing components in UI Framework definately require a different level of experience. I found it extremely beneficial to view courses about building standard web components (for example this Web Components & Stencil.js - Build Custom HTML Elements) . What I learned there I will probably use in my current Service Portal project and build some native web components. And I don't mean Service Portal providers.

But if any of you saw the preview of the new UI Building coming in Quebec you probably realise that what we see now is just a small part of what is coming. It is super exiting working with the new UI Builder.

DrewW
Mega Sage
Mega Sage

Do you happen to have a link to any presentation/video for the Quebec UI Builder?

 

DrewW
Mega Sage
Mega Sage

Ya I want thru a few Udemy courses to learn about them since I have been out of full web dev for awhile and I agree you need a different skill set but ServiceNow could have made things easier to deal with.  They also did a 180 as far as I'm concerned with having everything you need in the platform.  Now you have to have several external tools and and the code is not stored in the instance so you have more risk of loss.

Tommy Jensen
Mega Guru

Yes, Nathin Firth posted it on LinkedIn: https://www.linkedin.com/in/nathanfirth/

Tommy Jensen
Mega Guru

Well I can't say much but I will only do minor components in the current version of UI Framework.

Version history
Last update:
‎04-20-2020 02:35 PM
Updated by: