How to manage the “low code” portion of complex canvas apps


>>Welcome everyone. It is
10 a.m. on the West Coast. I believe that’s noon here in
central timezone for Daryl. So I have a webinar for you that
is going to be very interesting, especially if you come
from the developer side. But for anyone that’s getting into Power Apps especially
using Canvas and model, you certainly need to
know how to manage the low code portion of
complex Canvas Apps. So that’s what we’ll
be talking about. Daryl, welcome to the
webinars, how you doing?>>Doing good, [inaudible]
. It’s good to be on.>>So this one is certainly going
to be a very interesting one. As soon as you post this to
me that you wanted to do it, I immediately circled it and said, “We need to make sure
that we get the Word out” because the way that I always
described it is cold-blooded. A lot of people, when they first
start off with building an app, they’re indiscriminate as
to how they’re building it. Then they’ll discover, “Well, if I was a little bit more
predictive on how I built this, I could have done a lot
more efficiencies.” Is that pretty much what you were thinking when you
submitted this to us?>>Yeah, that’s pretty
much the same approach. You think if someone writing a book, they don’t sit down and
write the book perfectly. They have lots and lots of revisions. For some reason people try to hold themselves to a higher standard of, “I’m going to write it the first
time and it’s going to be right,” and they don’t think of having to
revise what they wrote. So yeah.>>Totally hear you. So let’s
just go straight into this. I’m sure that the
audience will certainly appreciate it and for those
of you who are here live, if you have questions, please
go ahead and submit it in the Q&A panel and we will certainly take time to
answer as much as we can. So with that said, Daryl,
let’s kick this off.>>All right. Thank you.
Hopefully you can see my how to manage low code
screen currently.>>Absolutely.>>All right. Awesome. Let’s
go ahead and get started here. So a little bit about myself. I started my own company in February. I’m a four-year MVP. Developer at heart, so I would be the non-citizen
developer at [inaudible] pro developer I guess if
people have drawn such lines. I do a lot of work in the XrmToolBox.
I’m a contributor to that. I have multiple plug-ins for that. They are my more screenshot here. I also do a lot of unit testing
with formally CRM, but now CDS. Just the Core CDS Power App platform. I also have my own
podcast, XrmToolCast, and I help on the XrmVirtual
online user group as well. I am from Fishers, Indiana, which is on the Eastern timezone. So it’s 1:00 PM for me rather
than noon, but that’s okay. Perfect good time to be able to hopefully share what I’ve
learned and go from here. So when Pervin asked me about this, this is really coming from me stepping into a new role
of my current client. I’ve been doing CDS, Dynamic CRM type of coding work for over a decade and now
they’re saying, “Hey, we have this new app that we’ve
been doing, this Canvas App, this Power App that
we’ve been working on that is needing to get
over the goal line.” They’ve been having a
citizen developer working on it for the last six plus months. Probably, there’s over 5,000 lines with the code at least when I
started on it that were in it, in this actual low code app, and all these different controls
and all these different places. So it was a huge learning
experience for me to do that. So hopefully, from my
experience with doing that, I’m going to try to share
that with you the audience and hopefully you could take a
nugget or two away from that. If you can’t, then you’ll
get all of your money back. So I can’t show the actual
app I’ve been working on, so I decided to take an open
source app that exist out there and that’s the Power Type
app by fellow MVP, Scott Durow. You can download it from this
GitHub site and get the link there. I’ll step back and say
this is a very clean app, Scott is a pro developer as well, so I would expect him to have
a high level of attention to decent code organization, and things being well written
and defined and created. He has done that so that’s great. So there wasn’t a whole lot of, “Hey, this is bad stuff, you
need to remove” examples. But I did try to go through it, just give some examples of things that will
actually be helpful for you and in your app
that you’re working on. So first let’s do a quick little
play through of what this app is. This is an actual game that he
created and it’s called Power Type. I was going to go
ahead and run it here. So in this game if you ever did Mavis Beacon stuff
back in the day, basically you start
seeing some words, you start typing the words, and the words should float in. Actually, you will see it on
the Team site with a lag, but that’s basically what’s
going to happen there. Type in words, they fill
out and you can erase all those words and
keep on going and get your typing skills up to snuff. So that’s the app in a nutshell. So this is the app
that we’re going to be taking a look in
and diving into today. I’ve added some extra
screens here as well. So by default, just
as these two screens. I would have added my
own down here as well. We’ll dive into those as well. But let’s take a look at the
first thing I want to show off, first thing I want to say, and this is actually the
biggest thing as well. So if you are dealing
with a large Canvas App, you’re going to be dealing with a
lot of issues that are revolved around having a low code tool
that has lots of code in it, but not the tools to maintain
that, if that makes sense. For ProDevs, we’ve got 30-40
years of development history behind us of people using tools
to create better tools and being able to have a better way of handling and managing
all their code base. In this low code Canvas App world, those don’t necessarily apply
as easily as you would like. So first tool that I created to
help ease some of that burden and to hopefully help to be
able to leverage some of the tools that exist
for regular code, not just these Power Apps formulas, is the Canvas App Packager. If you are a user of CRM or CDS or Dynamics for Customer
Engagement or whatever you want to. Actually, there’s no for is it? It’s just Dynamics
Customer Engagement. If you are using one
of those platform, you may be familiar with
a solution packager, and the solution packager
takes your export from your environment and it gets
exported as a single zip file, and it will go through and spit all that until all
these individual files, and it’s much easier to see what changes have actually
been made and to narrow down what is actually in this version versus the previous
version of your export. So that’s basically exactly what I intended to do with this
Canvas App Packager. You can get it on GitHub
with the link here. It’s just a basically
you’d take that zip file, and you run it through
the Canvas App Packager and it splits it out into
all different files. So let’s walk through
that real quick now. So in order to export an app, we’re going to go to the
actual make.powerapps.com. I’m going to select this thing. I’m going to say export the package
and go through the steps here. So this is the Power Type, export. Now if you had flows and
other things in here, they’d be showing up here as well. But currently that’s the only thing since this app doesn’t
connect anything else. So it’s very simple in that sense. Rather than waiting that go through, I’ve actually already
downloaded an earlier version. So let’s go look at that one. Let’s go to my downloads folder here, and actually go pull
up my command line. So this is the actual path I have
to my EXE that I’ve downloaded, the Canvas app package
EXE. It takes an action. So it’s either unpacked or packed, and then it takes the
actual file here, or the folder you want to unpack to. So that it’s Temp MS
Canvas app demo extract and then the name of the zip file. I’m going to bring that over
from my downloads folder, just got done downloading. Press “Enter” and it’s going to
run through and extract everything out and it’s going to
extract it out by screen. By screen, it will
extract into a folder and that each control is going
to be a separate file in there. Actually it’s going to be two files, there’s going to be a JSON file, which is some of the metadata for it and then there’s going to
be JSON file which contains all the actual formulas that you
can use some part of low code in. So that’s how the whole
structure of it works. So if I go and look at
what spit out here, we have these apps in here, there’s actual power
tied to this grabbed and then in here is the actual code. Everything else in here
is all this metadata that’s required for your app, but in here we have
the actual code and in here is basically where
you’re going to get all your value of what’s being
used, what’s not being used. So you have anything
that’s app level, this app there’s hardly anything at all in the
actual downloaded app. So if we open that JavaScript file, we’ll see that there’s a firm exit on start and then the size break. Those are the different app level
functions you can actually call. So you can see that
there’s nothing in the actual onStart for this app. But that’s just that and
then back up a little bit. There’s a JSON file as well and
JSON file is just metadata. I’m never touching the stuff, every now and then it
changes depending if there’s maybe a new version of Canvas apps, but that’s the JavaScript formulas. Actually, the formulas for the
power formulas were actually pulled out of this file
so that’s why there’s a dot JSON and a dot dot JS for that. So that’s pulling that all
out and then you could take that and then you can check that all into your source
control repository, either GitHub or TFS and then you have a backup in it that you can actually look at and be able
to see what’s going on. So the real question we have
of why would we do that? So it’s the why and the number one reason there throughout is about
some checking code. So if you’ve never found
an actual pro developer, why is checking in code helpful? What is it actually doing? Well, the first thing
it’s going to give you is it’s going to give you the
ability to compare differences. So let’s give a quick
little example here. If I am working on something
and I go, this power type, if we go look at the
actual formula for it, we’ll see that it’s
the parent width minus the label width divided by two
to be perfectly centered here. Now if for some reason
you accidentally double-click on it to type on it and you run then
double-clicking on it, you’re move it ever so slightly
and now you’ve lost your formula. Your x-values gone away. So that’s hurtful of hey,
what was that value? Now luckily you can
Control Z and undo that. But let’s say for example
that you’ve changed it, you’ve gone to some other
screen, you published, you didn’t know that you changed it, and then you’ve gone and
you’ve published it. Now you got an issue, what was that value before? I’ve lost my Control Z, I can’t undo, how do I know what
that value was or how did I even know that
I changed that value? In the last month, I’ve probably
removed the formula for positioning probably six or seven times and I caught it when I
was looking at my code death. So something you can’t do without having the code actually checked into somewhere and
seeing their differences. So let’s take a little WinMerge here. WinMerge is the open source
tool for comparing things. For checking for the Azure DevOps, you’d probably use
just Visual Studio, whatever tool you have
for comparing that. But I’ve got two different
extracts I’ve done. So I’ve extracted that version one, I’ve extracted a
version two and now I’m using this WinMerge to
compare these files locally. Like Guthrie will say, we have
our app folder we saw before, but we also have this screen splash. Knows that there is a difference
here if we look at the title, you can actually look
at the title JavaScript and we can open it up and see that it was 40 or it
used to be this formula. So now I can go great, I
know what the formula is. I can go back to my app. I can find that by the actual name of the actual screen and then the name of the control, they will title. So we’ll see that we are in
the label title file here. It takes a value in them. Now I’ve undone stuff without
having to undo the entire app. So PowerApps and Canvas apps, they do have the ability to
have version controls as far as you can go back aversion
or go forward aversion. But in a realistic scenario, usually your change 15
things and you don’t really want to go back just to fix the one and so it’s
painful to do that. So this is a way, a methodology for you to do
that without having to roll back your app and roll it forward
again and getting that change. So simple example there. Another example is finding
the variable usage. So let’s take a look at this
image player that we have here. Image Player1 has this little
spacecraft that Scott created here, which is nice little spacecraft. Let’s say we want to know how
does this thing move around? Well, it’s using this
Player1X variable. Cool. So where is this
Player1X really being set, where is it being used? If I have a bug in it, it’s
not operating correctly, where could that bug
actually be happening? You do have a nice view
action here to go to your actual variables
and go find this thing. The name was a Player1X?
Yeah, Player1X. So this isn’t entirely helpful. I can just look to see what’s
going on because it’s a very, very large function here. If I open it sometimes, you get lucky and it takes you to the actual area,
sometimes it doesn’t. Because this is all HTML, your browser search functionality
doesn’t search what’s invisible, only searches what’s visible. So you can’t find it very easily. So that’s a real pain point. So how does having the app
extracted help you in that? Well, if you use a tool like VS Code, which I highly recommend for this, free tool by Microsoft, and basically just go and
open the actual folder and select the folder that you
extracted everything out at. So that’s a code folder here, I should go to the main app, code.>>So once that loads, there’s little search function here. You can say “Hey, I want to
find where that player1X is. ” So player1X. Let’s go back. What I search for? Image player one, player one. So player1x and search, now it gives you every single
place that it’s used in your app. So very first part. This is the part we looked
at the screen earlier. It’s the x value for the
image Player one control. So that’s one we’ve
already looked at. So that’s good. So what’s
this other place here? Well, it’s also used in
the image work engine. So this is going to be
the look back to the app. Close this. That’s little tail here. It’s actually different icon
because it has to go through and change the way it looks. So it looks like it’s pulsating
when you’re playing it. It’s used in an x value
of this one as well. So that’s the second spot it’s used. You can see the formula there. Finally, it’s used in this game loop. Now if you’re doing a business app, you’re never going
to have a game loop that goes through and handles moving all your objects every
second or whatever it is that [inaudible]
setup for this to work, but you may have a main part of your app that
does a lot of the logic. So this is helpful to, to see
where everywhere it steps, so it’s being set here. It’s being used to set
the target x app here, and I wonder if I can
zoom in a little bit. No, I don’t know if there’s
a zoom control view. “Zoom”. Okay, well, I guess you’re going to have to
zoom in on your computer selector. So that’s set there and it’s also being used
here in this equation here. It’s trying to figure out if you’ve gone outside the boundary and
you’ve actually hit something. Then another set here where
it’s actually moving it to the new position, and that’s it. Those are the places that
it’s being used that. So without having the code
locally on your machine, and being able to search
for stuff, it’s very, very difficult to figure out all the places that if
certain variables being set, used or modified, even though there are some
tools in the app for it. But the more complicated the app is, the worst the tools
and the app perform, and the better it is to have local stuff that
you’ve extracted out. So although the Canvas App Package or is setup to actually
pack things as well. So if I wanted to go in
and change this formula, make it something
else, I can do that. But it’s scary from my perspective of doing that because if you spend any time making changes
and extracting, making changes and extracting, one little change in one
spot may actually require three or four other
changes elsewhere in the app for to understand
what the app is, what the definition of it,
what is that variable, is it a type of that variable? All that kind of stuff. So
going from local and packing it up and pushing it out to prod is something that I’ve really done. I think I’ve done it once, maybe twice and they’ll make minor changes. So I recommend
primarily this is, Hey, you’re just pulling it
back and being able to do [inaudible] what was in this version, what has this change made? All that kind of stuff
is stuff that you can much more easily get
extracted out your app. So if you’ve got nothing
from the seminar, hopefully you realize that using the Canvas app packager
can make your life much, much simpler and much
easier going forward. So that’s my first suggestion, and use the packager,
get it extracted, be able to look at it locally. So second option here, and that’s
to use buttons as functions. So buttons as functions is
kind of a funny idea here, but basically a very common rule that you will find if you are a ProDev, you should
already know this. If you are aspiring to be a
ProDev, you may not know this. If you’re [inaudible] dev, you
most likely don’t know this. But having formulas that are
smaller than your screen height. Makes apps much, much easier
to read because you can see all the logic in one place
and you don’t have to scroll. It also means that your
formulas are more specific to what you’re actually
working on and aren’t this big old gob of goo and not knowing where things
are, it’s hard to find things. So it’s just like if you had a book, if you had a book that was one
chapter long and was a 300 pages, you would have very little to no idea what the book
is actually about. If you’re trying to find
a certain part of it, you’d have to search the whole book. But if he had a book
that had 300 pages and 30 chapters and each of the chapters was labeled well
as well as what it was about, then you can much more easily find were the place in the
book you’re looking for. It’s the same thing with coding. The smaller the functions, better the names of the functions, the easier it is to go find
what you’re working on. So smaller functions
are more readable, more maintainable, there’s less bugs. You can also use it to
remove duplicate code. Then a feature I’m going to
add as well is to actually utilize a debug flag for showing
and hiding these functions. So if I go to my screen back here. Collapse this. So I’ve got
an example screen here. Here’s a different screen, not related at all to
the power type app, but just something that you may
actually have in your environment. It’s just having a subtotal,
and applying a discount. So let’s say I want
to make it 10 percent and now the total update is 900. Let’s make it 55. [inaudible] you can’t have a discount that’s greater than 50 percent or less than zero. So there’s a little bit of logic
that’s evolved around that. So how would you go
through and implement this and your actual app? What I’ve gone through
and set up here is I’ve set each of these OnSelect events. Actually, why is that not
giving you what I want? Onselect is false for everything. These things. Unchanged. All right, there we go. Don’t click “Unchanged. ” So basically both of
these text boxes, I’m calling another button that I’ve labeled as func validate
discount, the X button. So that one as well, the Unchanged. So both them are doing
the same exact thing. These buttons are hidden buttons that aren’t involved in the
UI, but they are functions. So what I also do is I have a
debug screen in here where I go through and I have an
ability to check this thing, which then actually calls the
Unchange this thing and this label, and are on select event. Here, I go through and I build
up this little debug context, which is a global variable that I can then set all these
debug values to. So this is also very helpful if let’s say you’re doing
an app where you want to be able to log in as
another user where you can’t log in with their account, but if on the onload of the app, you set a couple of
variables based on the user, and then you use those
variables elsewhere, you could override that in a debug screen and set
those variables to a separate user that
you’re looking up via name or e-mail address or whatever functionality
you want to do. So that gives you the ability
to be able to log into that. Then if you’ve logged
down this debug screen to only certain users
having access to it, maybe by clicking on the version, maybe for the version Text Box and where and you
click on the version, you check to see if they have a
certain role or a certain right. If they do, then you navigate
them to this debug screen. If they don’t, it just does nothing. Then you as an actual admin can go in and start to play around
a little more at the app, even if you’re not even
any web experience and a maker experience like this
in the actual app itself. You could go through and
do that. So this thing has updated this one variable that
I’m using in my context here. Now, we see these little
buttons that’s shown down here, and these are my function buttons. I’ve made them really ugly on purpose because you’re not supposed to see them, it’s
part of the main app. So those are the buttons. What happens here is, on
the onchange of this, this button gets called from
both of these actually onchange, this button gets selected, and this is the
validation role in here. So it’s going to go
through and expand this. So it’s going to go through
and check to see if the discount is less
than or greater than 50, or less than zero. It’s going to flip a flag, and then it’s going to eventually
call this other function. I’m going to walk through
this a little bit later. Let’s call this other functions. So this one calls this one,
which is a validation, and then this one does
the actual work of calculating the actual
percent discount. So total equals the
discount percentage times the actual subtotal
to get the actual total. Now, this is an extreme
example where I’ve only got one line and a function that may be taking it to the
extreme, it probably is. But just wanted to
give you an example. If you’ve got 20 lines of
code or 15 lines of code, somewhere in that round, you may make more sense to put
it out to a function. So that’s my MVP tip there. One thing to be concerned with, or wary of is that you’ve got to handle delayed execution
when you do that. So if you don’t know
what’s delayed execution, I’ll try to walk that through here. When a text value is changed, that’s going to trigger the
onchange event to get called, which then calls your formula. The formulas then are
going to actually select the “ValidateDiscount” button. That doesn’t actually call the
code and the formula right away. What that’s going to do
is put it into a queue. So there may be other selected calls that are waiting to
process on the queue, and now this new
ValidateDiscount call goes on the queue of things
that need to be processed. But before anything is processed, the rest of the formula in control
is going to finish processing. So if you had analogical that happened after the validate discount, it’s going to process. Now normally encoding. If you’re just a ProDev, and you want to refactor
out of methods. So you’ve got a 100 lines of code, you want to take 20 lines out and
put in different function call. You do that and you don’t worry about having that to be
executed in a delayed fashion. That function called, executed, and finished, and then come
back to the calling point. For Canvas app, you don’t
have the ability to do that. So it’s got to go to this queue, and the rest of the function
is going to finish processing. So generally, if you’re going
to call it to a function, you either have to ensure that it
doesn’t have any dependencies, or anything that happens
after that in the function, or you put at the very
bottom of the function. So that’s what we did in this case, as we set at the very
bottom of the function. So once that actual onchange event of that subtotals finish processing, then the items on the
queue start processing. So all those selected
calls will process, and then finally now our validate
discount call get processed. When that happens,
it’s going to actually trigger that validate
discount logic to run. So this is a method to make
life simpler or easier, but you have to also
be aware of anything that you may be doing that it’s going to have a dependency
or something else, because you are going to introduce
delayed execution in your code. So as much as Canvas apps
has brought in the ability for non-Dev users to be able to do some awesome
and very powerful things. Once you tart getting into
the complex realm apps, you’re going to need to step
your game up even more, and start understanding how
code actually executes. That’s where even posting on
community is helpful as well. Hey, this is working.
Why isn’t this working? Or hey, how should this work
and that kind of stuff. So that’s my warning. Another thing they’d
be concerned about, are that race conditions
are possible as well. So that race conditions are involved
with those late executions, but they’re also involved in you’re dealing with external connectors. So let’s say that you have a function
here that selects a control. So that places that call in a queue like we had in
the previous example. When that call runs, it makes a call out to
an external connector. When that happens, it’s
going to yield control. What I mean by that is, normally in this queue, if I go back to this queue here, normally the queue will
process completely, whatever it happens to be, and then the next thing will get called. But if this count call actually
does something else outside of it, if it makes a call out to
the external conductor, it will cause an actual issue and it won’t finish executing before the next item on the
queue is processed. So this is a little bit
hard to talk about. So let’s go through and look
at another example here.>>Before you go on, you have two questions and a
statement I guess. First question from anonymous. Are the calls to the queues
executed in order, eg FIFO?>>Yes. That is a
first-in, first-out order. Yep. You saw there.>>Will Dorington, made a statement. It’s good to know that Azure
DevOps Power Apps build tools has a great unpack
solution function as well. He just puts a smiley face. So I think he was just being, that he was just making a statement.>>Okay.>>Thanks. Last question
that just came in. Is there any published plans
by Microsoft to directly integrate VS Code or
Visual Studio Code? So I guess that’s more on my side. There aren’t any direct
published plans. There is definitely talks, but there isn’t direct
published plans yet.>>I will add to that, even though I have NDA
stuff to talk about. If you actually look at
how code is structured, and the metadata that is structured, it isn’t as simple as, here’s a code file, go to town.>>Yes.>>There is a lot of metadata that you can look in the
actual expert or app to see, oh, here’s where
everything is defined. So any tool that reads this is
going to have to understand all this other jumbo stuff
before it can actually give you a good debugging experience or good
actual programming experience. So that’s a difficult ask. I know it’s a huge thing that
I want to personally have, and I will do everything I can
to tell Microsoft to do so. But that’s a pretty big ask.>>It is a very large
hurdle to clear. It is certainly something that’s been discussed behind
the scenes here, but it’s not something
that we can just simply go click click
click and it’s ready. So good question though. All right. So I think that’s generally
the questions that we add.>>Okay.>>So continue.>>All right. So going back
to the first question. You have, I must be
processed in a FIFO manner. We would have to be worried about that when you deal with
calls that are external, because those yield control. So I’m going to have a little
app here, a little button here. That all it’s doing, it’s clearing this first account and then it’s
selecting these two buttons, the “GetAccount” and “GetName”. The GetAccount button is going
to refresh my account to make sure that it’s always grabbing
the latest version and actually going hitting
the actual database. If it doesn’t do that, then it’s going to
potentially grab from cache. When it grabs from cache locally, it doesn’t yield control. So that’s a little caveat here. So I do that to make sure that we are actually hitting the database, and so we’re actually going to get the very first account for my
accounts collection from CBS. The second one, process here, and it’s going to check
to see if it’s blank. If it’s blank, it’s
going to give an error, and if it’s not blank,
it’s going to give the actual name, and
set that to the name. So if I hit my button here
and actually try to call this by moving it. It
hasn’t moved, but okay. So I hit it, and you can see this is actually taking
a while to select, and that’s because once that started to operate,
the GetName called. So the GetName called and it updated
the text label here to error, and then finally the
GetAccount finished. But it doesn’t update the label, it just updates that variable, and so we are left with error, which is not that great. So how do you get around that issue? Let’s look at the simpler
way, works are now here. I’ve created a new variable
here, first account. It goes and grabs the first account. So in this case, I do any of the
work that is involved externally. I go and I call it from, actually I better refresh this too. That is GetAccounts,
right? So in this case, I do any of the work externally
in the first button. So that way when this call is made, it’s going to yield
execution to the app. Once the account comes back, then it will continue processing
and process these two buttons. So this button is a
little bit different than the original, in that, it’s just getting the
actual first account, this actual other variable that
we created and setting it. So it’s all local, there
isn’t an external call, and then it calls this GetName. This button calls
this GetName as well. So now we’re on that one. You can see now it
takes a while for it to go get the count. But then boom. Now we have Name is Seal E Darryl. That’s just a little joke there. But anyway. So that’s
one way to do that. It works for now because you have
to be careful that you never ever put in a external call in
either this button or this button, because if you do, it’s
going to break your app. Potentially, it’s going to
cause a race condition. So just be careful that that’s
a dangerous way to do that. The more, I’m going to break this
again so we have error again. The more safer way of doing that is to not call two
buttons simultaneously, because that puts a
dependency that ensures that that first button called doesn’t have anything that the
second button call needs. So this one you call this
other button, and in this one, it does the work it needs to, and then when it’s
finished processing, it calls the next one. So on here you’re chaining things. You’re chaining one
calls the next call, which generally isn’t all that great. I’d prefer to work the other way, but we don’t really
have an option in this. So this is the way to
ensure that even if I start adding multiple things in here
that are doing external calls, I’m never going to have a
case where this button font GetName threading button that it doesn’t actually
get called until we’ve actually done the call
to the server and it’s populate the data that acquires. So that’s threading. Threading is complicated. It’s something that,
especially for our ProDev, that you’re going to really
struggled with for a long time. But those are just some
general rules to abide by. Any questions on that
before we move on? All right, I’m going to take
silence as a good thing, that I did a good job explaining, not that I completely lost you, so let’s hope that’s the case. Naming things. Naming things is hard. Naming conventions are like
way harder than naming things. The good news is that
Microsoft does have a fairly decent coding
standard guideline. Then there’s the link for it. It’s a PDF that actually
even goes down to the TLAs three-letter acronym level and give some examples
how to do that. The biggest caveat
they caught out there, the biggest kind is,
this is not the Bible. This is not you have to
do all these things. No one’s going to look at
your code-base and go, oh, that’s wrong, don’t do that. But the point is, is for you
or whoever’s in charge to make an educated decision as far as if this is something they
agree with the docs actually. This guideline actually does
a fairly good example of saying why should you do it this way? Which I love rather than
just plainly saying do this. There is a company once where they used all of their JavaScript naming conventions and applied in the C# or maybe it was the other
way around, I’m not sure, that caused me great deals of pain because there’s
reasons that they are done differently in each language
and to just throw them out the window like that was
really affecting my OCD. So this is a good starting
place, you can say, all right, let’s look at these things and then very quickly you need to come up with reasons why you’re going to use that particular set
of the naming conventions or not. For example, they always
recommend putting screen and the name of the actual screen name. This is primarily for screen readers. Someone can’t see and they want
to be able to look at that, they’d be able to read
it off the screen. So maybe that’s
something that doesn’t apply to your work environment, maybe it’s something that you
don’t have to worry about. So maybe that’s something
you don’t want to do, but they give the reason
why they do it that way. So I tend to find, and I get my examples here that
I like carrying the actual thing first and then the actual Hungarian notation that
actually what it is later, it just seems to be
a lot more readable. Get function getName
threading button, there we go. That’s the name
of that one right there. So that tends to make things
that just a little bit easier for me in when I’m trying to search
and find something in the code-base at the IntelliSense, I know it’s a function, so func. Then I can get whatever the values are or funk options
are, if that makes sense. So all right, so those
naming conventions, highly recommend looking at that, just this next screen here as well. So I always recommend
to use Camel Case, which starts with a lowercase
and then uppers for anything that’s specific to
a screen and not global. So anytime you’re using
context variables, I always have them be lowercase to begin with and then uppercase or any other
words we have in there. That’s called Camel Case. Then I use Pascal for
any and that’s global. Now why do I switch it
that way versus the other? Primarily because collections are global and you can’t make them local. So those are automatically
global and those are usually set it to
be a capital letter. So I just leave it that way as well. But for some reason that you want
to switch that around, you can. I also think having a
capital letter gives it more importance, like
it’s more prominent. So that’s another reason. So recommend using Camel Case, which is starting the
lowercase letter and then uppercase for any new words
after that context variables, everything else would
be Pascal casing, which is the first letter
is also capitalized. Indenting. You will find
many a times that you decide to either add a statement
or remove an if statement. Although the indenting in the
app itself is fairly decent, it isn’t perfect and I
tend to do it myself. So for example, this is
not the one that I wanted. So our question while I’m
searching for this at all, no?>>We do have a question that
just came in from [inaudible]. What point or conditions
would you suggest removing a large chunk of code from a Canvas
app and into Azure Function?>>Well, obviously, if it becomes
unmanageable in your Canvas app, you’re going to probably want
to try to move that out, but the other issue there is yet to know what kind
of app you’re working in?>>Yeah.>>If you’re on a field service app, if you’re on an app where data
connection isn’t reliable, you can really, really
make a poor experience for the user by starting to move all this functionality out
to different functions. So I usually try to do the
best I can to start dividing the code-base into smaller
functions that I can then work with by using those
button features on the app, rather than immediately
jumping into the flows. Just because you don’t know if you’re going to have a
connectivity issue or not. So that’s just a video where, hey, if you want to
run that out, great, go that route, do that,
just be aware of that. Now you’re dealing with stuff that you’re also dealing with
potentially the more cost as well. We had an issue this week actually, where the current clients they went
over their allotment for flows and the Canvas app broke
multiple times because of that. So just be aware that that’s another
layer of another choke point, another layer where you can have
potential issue when you do that. So this is the init timer function that Scott has and this
is what sets up the actual where things are on the
screen and all that fun stuff. It’s formatted very well. We got this really weird, ugly blob, which there’s really not
much you can do with, it’s just what it is. I think he actually generates
this from some other app. So he doesn’t even edit it, it’s just paste it in there and
it’s just code that’s in there. So if you go and you
happen to copy this first, if you happen to remove
the formatting and use just a standard text formatting, now your functions really, really long and this right here is not any more readable
than what it was before. I’d argue that it’s actually less readable by a rather
large margin because when I want to actually go
down and edit the next thing, I got to go in this are here. I don’t need to scroll through 40 lines of code to see
that we have a loop here. So this is much more
readable, that approach. So you will find that, hey, now I need to indent
things differently. That’s when you can use a tool, you can do it in VS code, it’s a little more difficult
to key these images for it, but it’s also very easy
to do that Notepad++. So if I open up my
Notepad++ that I have, once again free tool, free download. I decide that let’s say we’ve
got a lot of code here. I don’t want to do that all the way. Let’s do the simple way here and
do the function here about this. Right.>>So I’ve got a lot of code here, and let’s say I want to indent
that, holding them all, you can actually
select lines you want, and you can indent those
over probably by two, or you can decrease the indent. So that makes it very
easy to go through, and not have to remove all of your formatting in the
actual formula bar, and be able to actually
start using it. You can even just copy and paste
what’s in that Formula Bar, out of the Formula Bar and do
this and start working with it. So if I wanted to take Scott’s
code here and take it in here, as I don’t want to put
this in an if statement, I can select those lines, indent them and
everything works great. All right. So that’s using
Notepad for indenting. Any other questions?
So is everyone good? We will have a little bit
more time at the end. So if you have a question,
feel free to ask, and also, I want to have more time to having to be also share some tips as well. I’ve only been really working in Canvas apps about
three months here. So you may have twice as much, three times as much
experience as I do. So if you have some other
things that are very helpful to share, that
would be great as well.>>It looks like we
also have Brian Dang, one the attendees and
he’s certainly press wanting him adding more
information to it. So feel free you got backup.>>Thank you Brian.
You and I communicated at Twitter or LinkedIn,
I can’t remember. Entice them with my screenshot
of a complicated formula. You could do some loops, which I didn’t think was possible, but you can actually
do loops in Flow. I had an instance and an app, where they were wanting to make a call out to an
external app, failed, they wanted to call it again,
and they wanted to call, they wanted to do three retries, and so they duplicated
the Logic three times. That’s bad. Don’t do that because very easily you
can change the Logic one place, not the other two places, and now maybe it works in one spot, and not the second, or third time, and you don’t know that,
it’s very difficult to test. Do your best not to
have duplicated Logic. You can use loop to do that. It’s a little more complicated. I’m not going to show that in here, but you can actually do
that with a tower control. Eric has a very good video on that. So I recommend you
check that out if you ever need to get that situation. Here’s part I will not budge on, I said the coding standards
is not the Bible, but you do need to be religiously zealous in your indenting and
formatting approach that you use. If you are the sole creator and maintain for apps in your
environment, guess what? You get to define that. If there are multiple people, you need to include them and come up with how you’re going
to format things. You’re all being able to
read things the same way. That’s just a requirement
in order to be able to figure out what’s
going on the codebase. So just know that ahead of time. So here’s another interesting one. Don’t use avoidable if’s. So an avoidable if, is an if
that’s not necessarily required. So if I look my ValidateDiscount
example button, I mentioned we’re going
to go back through here. So now we’re going to do that now.>>[inaudible]?>>A little bit. Cool. So in this example, I was checking to see if the discount is greater
than 50, or less than zero, and then I was using that just to update this error
message to say,” Hey, it’s true, or it’s false?” Because it’s a Boolean, I don’t need to be
writing an if statement. I can just be directly
assigning the result of this comparison to the function. So these one, two, three, four, five, six lines of code are basically exactly equivalent
to this line of code, only it theoretically runs a little bit, actually
this one is faster. It’s the same exact thing basically. Maybe it runs a tiny tiny tiny, an infinitesimal amount than
will ever be able to notice, even if you do it finally
any times faster. So that is way way more readable. This line is versus all these lines. Next statement here, use commas
for else’s on a new line. So if I happen to
have this over here, although this is valid and
it compiles just fine, it’s difficult to
notice the comma here, and if you have a lot
of lines of code, it’s even way more difficult
to notice that comma. So I highly highly recommend to use a comma on a separate line by itself, for the else portion
of your if statements. I can’t recommend that enough. That makes it way easier to see. Here is my if. Here’s
this, here’s that. Second thing here,
try to avoid Not’s. So previously, and I actually
wrote this, I said, “Hey, if we don’t have an error, then select this value.” Well, then I also decided
I needed to say, “Hey, we do have an error, I need to show not applicable,
or not available here.” So I originally wrote it like this, and now these statements swapped. It’s much harder for our brains, as wonderful as they are to actually read a Not,
that it is not a not. So if Discount Error, great verses if not Discount Error, then that takes a lot more brainpower just to be able to go
look at something, and much easier to make a mistake. So try to avoid your Not’s. If you have an if statement
with an if and else like this, and you have a Not here, search the order of these things,
and remove your Not. Simple. If you only have
an if without else, now you’re not needs to stay in
there, and don’t worry about it. It’s no way you can change that. That’s are questions
on ifs and elses. Another thing that you
need to be worried about, is to define how your
data for your screen, or your app is actually
going to be reset. What I mean by this is as you
navigate from screen to screen, you need to make sure
that you are pulling in data from previous
app, or previous session. So I’ll tell you a
quick story in this, when I first transitioned
over from the CDS world, dynamics world directly
into the Power Apps, Canvas App world, they were having
a bug and they’re saying, “Hey, this if statement is not firing, even though it should be firing.” I was looking at the
Boolean value they were looking at and I said, “Hey, where’s this value being
defined under rule? Where is it being reset at?” They were never
actually resetting it. So what would happen
is they’d go through the service tech that
was on the home, they go to the first customer, it would say, “Hey,
this is valid, grade.” They go to the next customer, they want to reset the app, they just click on the next job, they got process, and now they’ve got stale data from the previous app, that’s already preloaded
when they load the form. So just are the screen. So just be very careful
that you are defining, in the on visible, maybe you need to reset all the
context variables for your app. In the app load, maybe
you need to reset all of the global variables. Maybe you need a Refresh button on the main screen to reset
all the global variables. If you want to be able
to pull new data, these are all things you need
to go through and define. So you need to establish
that upfront before you even start creating and designing
your very first screen. Then I believe, we’ve
got one more here, and this is the last one, and then we’re going to
move on to the questions. So if you’ve got a burning question, then feel free to start
typing that up. I guess so. Another thing I found very helpful is manually adding a version
number text field to the app, and then, to also store in
a data store some service. If you’re connected
to Azure database, connected to CDS, create
store in one of those spots, and the reason I say to do that, is that allows you to enforce your users to actually
update the app. By default, if I publish a new app, that does not force the
user to update the app. If they are in the middle of doing something that may be a bad thing. If I’ve just typed up 10 pages
worth of notes on a customer, and all of a sudden I’m forced update the app before
I can save my data, you’re going to have
a very angry user, or frustrated user on your side. In this case though, it’s just
being able to force an update, that on a certain spot where
you want to check for that. That’s a great feature
to be able to have. Another advantage to that is
when you are testing things, and you may have a QA person
that’s working with you. If you’re lucky enough to have
somebody else helping you in that. It’s very nice to be
able to say, “Hey, are you on this version of the app, and have it showing in the screen. It also, that version number also can use as your debug
tool too if you want, click on that version
number, and it takes you to the debug screen. At one point in time,
I actually thought it, he said the economic
code for going through, and getting into the debug screen, typing up, up, down,
down, left, right, left, right, whatever from the counter, 9-10 days, I actually
thought of doing that, but I ended up going a little
more realistic approach, and it in the database I was using, but anyway, I digress. Funny story, but that’s just another example of that
version number is helpful, because you can’t really get
the version number of the app, and then just giving
year, month, day, and then whatever version
of the day you’ve updated, it makes it very easy to
figure out how old an app is, or whatever is going on. So here is my contact
information on Twitter, LinkedIn, YouTube, and GitHub. You want to check out my stuff. If you do send me a
message on LinkedIn, a request and LinkedIn
please include a note of, “Hey, you saw me in
this presentation.” Or “Hey, you use this.”
Or “Hey, you saw that.” I generally don’t accept invites of people that
I haven’t met before, or I don’t know what
their connection is. I like to have that
connection. So that’s just my own request to know
why do I know you, how do you know me, and
I like having that. So just add a personal
note, you need to, and yeah, that’s my
request for that maintain. Besides that, feel free to reach out. So questions, you have
any questions for me?>>Nothing new has come in. Certainly been an engaged audience.>>Is anybody have anything they’d like to share
about something that I missed that they found useful
when dealing with large apps?>>Or even in some
different approach.>>Or somewhere that I’m wrong. That’s practically possible too.>>This is all meant
new to this world so by no means are we saying that
we are the true experts. There’s always five ways
to skin a cat, as I say. Probably a bad choice of terms, but you get what I’m saying.>>Don’t let Sarah Kirklin know.>>I was just thinking that.>>Yeah. It’s morning time here. Well, I guess if there
are no other questions, there are ways for you to get
a hold of Daryl on the screen, and certainly ask him questions. Daryl, this has been so much fun. It is rare that I get
the Daryl back into the developer world and
peak back into code. So I can certainly say that I
had a lot of fun with this. So we certainly want to have you
back on to talk more about this. I’m sure there’s always
more things to gleam, and I will certainly
say that we should have you two new questions that came in because people were typing quick. Robert asks, “How do you get
past the 500 return limit?”>>Five hundred return
limit for what?>>He didn’t leave much
information on that. Maybe he’ll type in a subsequent
piece of information. Phil Cole has, “Do you have
any tips for offline usage?” That’s a good question.>>I have been lucky enough
not to have to deal with that. But we did have a MVP that
just recently posted a lesson. I think it was Canadian. Was that the [inaudible] Was
he the one who did that one? I can’t remember who did that one.>>I think what we’ll
do is we’ll get a linked together for some of
the various off-line options. I think the big thing that we pointed out is one of
the earlier questions, when you start making an app, you really need to start thinking
about how it’s going to be used before you get too
deep into creating code. Because if you do end up
with a lot of code bloat in one area and you want to obviously
take advantage of Azure, that’s where you can certainly
run into that challenge of there. Without connectivity,
then you won’t have that function or that
piece of code available.>>Yeah. They are the block site for that but I can’t see
[inaudible] apps. I’ll find tips and tricks, from stuff and tacos.>>Certainly go to the
community sites that exist, either on community.dynamics.com
or community.PowerApps.com. There’s a wealth of information
around offline as well as in general questions that
people have run into where we’ve answered them as
well or the community has.>>That’s a great point there too. If you’re struggling
with something or are wondering how are
you doing something, that’s a great spot to go to to
get answers as well. So yes.>>Joe. Hi Daryl. That was great, thanks will
probably think of a question later. So you’ll get to see
each by Joe kills later.>>Okay, all right. Interesting.>>Anonymous really
liked the session. Big thank you. So that’s awesome. Phil posted a link about 500 limits, so I’m not going to
open up the link yet. Here’s a link to what Daryl
was talking about from Brian. So he’s got a Twitter
posts that from Oliver, Clint. In regard to collections, there is a limit of 500
records that can be returned.>>Okay. Well, the reason we->>[inaudible] That’ll
be included, does give an option of how to overcome it. I mean, it kind of depends
on how much information and what you want to do with
that collection thereafter. Meaning could be a case
where you want to collect as many as are in that could be 10,000 records or a 100,000 records. You have to gauge on what you
want to do with that collection after you built up multiple collections and
then aggregated together.>>Totally.>>See the definitely calls out that what we were
just talking about it, so it could be performance
thing that you might run into as well collecting
that much data. This from anonymous,
every control needs to have a unique name and
that’s a question. Do you have a tip for
naming within each screen?>>Okay. So if I go back
to my app real quick, the general way of naming things, at least I think it was defined in the actual document that I had for Microsoft lists the
Hungarian notation first. It’s like LBL version,
timer, whatever. What I tend to do in mine is to put that at the end but
you put at the front too. So I didn’t bother to number
some of these things. So shame on me for not
giving good example here, but here’s one total and then the ex’s signed a two letter acronym for the screen. So that’s my example,
“Total example texts”. So that was how I had read that
variable rather than example, total example text seems
to be a little bit easier. Just example text are easier
of rolling off the tongue. So having that standard of including the screen name in
it means that you no longer have to worry
about any other screens. That also makes it easier to know what screen that
control is on as well. So as much as most programmers, most pro devs have shared
Hungarian notation for years. That’s just putting in the actual name of the actual thing in there, so TXT would be the [inaudible]
rotation, that total example. That’s something that I actually define to be helpful in
this Canvas app world.>>Also, there’s
still more questions. Where can I find the recording? The recording will be posted on community.dynamics.com and the official YouTube
channel for dynamics 365. Once it passes captioning as well as accessibility so it might be a week or two before
it shows up there, but we’ll certainly let
everyone know when it’s posted. Jason Cosmin also adds in, screen names should be meaningful because they are used
for accessibility. Yes, absolutely correct and Jason I’m glad that you’ve
got your luggage back. William Darlington, “Will the recording of this
presentation be shared? Totally enjoyed it.”
Thank you, it will be. I think that runs through all
the questions that we’ve gotten. A lot of good feedback, a lot of good questions. I’m glad everyone saw value in it, we will certainly bring back
Daryl for some more coding fun.>>It sounds like actually I got
to ask Jason the question there. So the name of the screen, is that what’s read to the user when they go to a
different screen then?>>I believe so.>>Okay, all right. So
these are bad screen.>>It should read from the screen
name itself as it reads aloud.>>Yeah. So this should
actually should be the way that’s actually.
All right, cool [inaudible]>>Otherwise, [inaudible] if those
examples currently referred.>>Yeah. All right, so I was
thinking from a Creator experience. Well, that isn’t necessary, that does a helpful but yes, if that is one area
where we crossover from the maker to the
actual user of it then yes, that makes a whole lot
more sense that you need to have screen rather than [inaudible] so shame on
me, and a lot take those.>>That’s good to know. I
did not realize that myself initially when we were all trying
to be accessibility compliant.>>That make sense.>>I think screen names
Phil does confirm, filming screen names are read by screen readers and there
should be real words with spaces.>>Okay. Cool.>>Well, that’s awesome. I think
we’re at the 11 o’clock mark. So we’ve done an hour and you can see that Daryl saving after putting in some real
names for the screens. So we’ve certainly
learned a little bit. We can part at some knowledge. I think that’s always a
good thing on a Monday, especially, you know, it’s a Monday. With that said, I’m going to go
ahead and put a stamp on this. We’ll go ahead and put the
recording, do some markups, make sure that it is accessibility
compliant and then we’ll post it on the official YouTube
channel for Dynamics 365. But it also sounds like
we’ll probably post this up on the Community.PowerApps
site as well, just since there’s a
lot of overlap here and a lot of lessons
learned that I’m sure that the General Power
Apps Developers would certainly glean a lot of cool
information from not just dynamics. So with that said, Daryl,
thank you so much. It’s been certainly a pleasure and for everyone that
was on the call, thank you for attending live. We will certainly start back up
very soon after Thanksgiving. We’re going to take off the week of Thanksgiving since everyone
should spend some time at home with fam and so we’ll take
the week off for Thanksgiving, but then December second
will be back with Renato and he’ll be talking
about Business Central and Flow, which was a change to power automate. But for those of you who
want to know how to use Business Central and power
automate together effectively, [inaudible] will be on and he
will talk more about that.>>Thank you [inaudible]>>All right. Thank you all. Put a stamp on this, we’re done.

You May Also Like

About the Author: Oren Garnes

Leave a Reply

Your email address will not be published. Required fields are marked *