logo

NJP

Now Experience UI Framework efforts and my experience with it.

Import · Apr 20, 2020 · article

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.

image

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%5Ffunctions

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.

image

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

image

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. image

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.

View original source

https://www.servicenow.com/community/developer-articles/now-experience-ui-framework-efforts-and-my-experience-with-it/ta-p/2307903