Ready, Set, Building Applications With GO!
Ready, Set, Building Applications With GO!
Ready, Set, Building Applications With GO!
NOV
DEC
2020
with GO!
Sponsors:
Powered by
Features
8 Simple ExpressJS and
A 65 T he Complete Guide
TypeScript Project to Suspense in Vue3
Sahil walks you through a simple ExpressJS-based Web app using TypeScript Suspense is a tool that makes sure your content is ready before displaying
to help you get started using these great technologies together. it. Bilal explains this complex concept using example app code.
Sahil Malik Bilal Haidar
US subscriptions are US $29.99 for one year. Subscriptions outside the US pay $49.99 USD. Payments should be made in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards are accepted. Bill Me option is available only for US subscriptions. Back issues are available. For subscription information,
send e-mail to [email protected] or contact Customer Service at 832-717-4445 ext. 9.
Subscribe online at www.codemag.com
CODE Component Developer Magazine (ISSN # 1547-5166) is published bimonthly by EPS Software Corporation, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.
POSTMASTER: Send address changes to CODE Component Developer Magazine, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.
it was the latter rather than the former. It was a with other humans. This is probably the most dif- must have our conferences online. This’s a big
slog. The question came up: How do I get myself ficult of all the changes to our world. I’m a social shift because it limits one of the best features of
mentally out of the mud and onto a dry road to- being and I bet that many of you are as well. This conferences: the hallway talk. Although it’s easy
ward an editorial? limitation has caused a massive ripple effect to to give a technical talk online, it’s very difficult
the entire world’s workforce and that’s especially to replicate the hallway aspect of in-person con-
My general strategy is to seek out material that true of software developers. ferences. How are you handling the social aspects
helps me find inspiration either for the concept of your technical regimen?
or to add material to my already existing theme. As a software developer, I find myself on planes nu-
In this case, I was looking for inspiration to sup- merous times a year. Over the span of 25 years, I’ve Another consideration is working from home. For
port my already existing theme which, by the flown 2,000,000 miles to attend user groups, meet me, this wasn’t a huge adjustment as I’ve been
title, you can see is: The New Normal. with clients, or attend/speak at technical conferenc- working at home in one form or another for two
es. For me, this component being completely absent decades. The biggest adjustment for me is that
I’ve been sitting on this idea for the last few is probably the biggest adjustment. It’s mid-Septem- I now have a high-school-aged child home tak-
months and was trying to find the proper words ber as I write this, and it’s been a full six months ing online virtual classes. I consider myself lucky
to start. This is where I got stuck. Generally, I since my last flight. That’s a new record for me. not to have an elementary-school-aged child at
start my editorials “old-school” by writing them home.
on paper. If you look at Figure 1, you’ll see that That leads me to the next part of the new normal:
the start of the editorial had a bunch of crossed virtual technical conferences. The concept of in- Those two areas are just the tip of MY iceberg.
out lines. I was way stuck. person conferences is out of the question so we I appreciate the fact that we all have our own
unique challenges difficulties to deal with.
I pulled myself out of the morass by look- My hope is that once we have better
ing for inspiration. I decided to look at treatments for COVID-19 and a vaccine to
what I wrote for the Nov/Dec 2019 issue. prevent its spread, we can take away the
The Nov/Dec editorial was an interesting good parts of this new normal and build
one as I wasn’t the author of that edito- on them. For instance, if you’ve adapted
rial. That editorial was written by my edi- to the lifestyle of working at home, you
tor, Melanie Spiller, and is called, “Sock, may want to re-evaluate where you live.
Sock, Shoe, Shoe” (https://codemag.com/ Your choice of where to live might now be
Article/1911011/Sock-Sock-Shoe-Shoe). limitless. Or if you want to attend a con-
I loved this editorial, as Melanie wrote ference, you may find that some of them
about her experience of taking her normal continue to offer online versions and that
morning walk but being forced to reverse you prefer that for a multitude of reasons.
the route as there was construction on her I may attend some at home and some in-
normal route. What Melanie learned on person, once I have the choice.
this walk was there was a whole universe
of things she never noticed even though I’m hopeful that we’ll return to some sem-
she had walked the same route for years. blance of normal in the coming months.
Melanie’s perspective had shifted. It’s yet to be determined what the defini-
tion of normal will be in the coming years
This leads me to what I want to convey but I, for one, am optimistic that we’ll
in this editorial, a discussion of the “New end up in a better place than before. That
Normal.” Like it or not, we’re faced with better place will partially be the result of
a lot of change, some of which may be taking a new and unexpected direction,
permanent. For many of us, our world has much like Melanie talked about in her
been turned upside down and we’ve been 2019 editorial.
forced to take a new route. This change in
our world view isn’t because of any man-
made activity this time, but because of Rod Paddock
the spread of the COVID-19 virus sweep-
ing the globe. There are so many changes
to our way of life! The primary change is,
of course, that we must now limit contact Figure 1: Making a few preliminary notes
6 Editorial codemag.com
NEVRON OPEN VISION (NOV)
The future of .NET UI development is here
A c c el er a
U
GP
te
d
Re
n d e ri n g
The
Thesuite
suitefeatures
featuresindustry-leading
industry-leadingUIcomponents
components
including Chart, Diagram, Gauge, Grid, Scheduler,
Rich Text Editor, Ribbon, and others.
I’m kidding, I’m kidding. In fact, any statement about Ja- Running this command should give you an empty package.json
vaScript produces so many strong emotions on either side, file. In your package.json file, you’ll have many configuration
it’s not even funny. Since I started writing this article, there values. The three main configuration values I’m concerned
have been at least five new JavaScript packages or frame- about here are dependencies, devDependencies, and script.
works released.
• dependencies are what the project depends on. These
A few days ago, a work colleague reached out to me. He hap- are the node packages that the project is going to
pens to be a .NET programmer—a very good .NET program- need at runtime. In other words, this is something
mer. For some crazy reason, he found himself stuck on the you intend to ship.
Sahil Malik task of building a Web application in NodeJS. • devDependencies, on the other hand, are the node
www.winsmarts.com packages that your project depends on, but only at
@sahilmalik Easier said than done, right? The problem is that in the classic coding time, not at run time. Although these node
Microsoft world, so many decisions are made for you. You can packages are very important to the project, you have
Sahil Malik is a Microsoft
simply create a new .NET Core Web application project and no intention of shipping them in the final version.
MVP, INETA speaker,
you’re ready to go. This isn’t the case in the JavaScript world. • scripts are what you run and scripts can call other
a .NET author, consultant,
scripts. A typical NodeJS project is comprised of many
and trainer.
There are so many decisions to make. What version of Node- scripts. In this case, the scripts will have the respon-
Sahil loves interacting with JS should you use? What node packages should you take a sibility of building the project, cleaning the project,
fellow geeks in real time. dependence on? JavaScript is a very flimsy language; can etc. Let’s get to scripts in a moment, once you have
His talks and trainings are you take advantage of TypeScript? How do you ensure that the basic project structure created.
full of humor and practical you’re following best practices? Do you want to have a pro-
nuggets. ductive development experience, like pressing F5 on your Let’s start with dependencies. The project is going to be an
keyboard to run the project? And so on. ExpressJS application and a TypeScript application, and it
His areas of expertise are will require, at the bare minimum, two things. It’s going to
cross-platform Mobile app This is perhaps the biggest frustration of working with Ja- need a rendering engine and it’s going to need some con-
development, Microsoft vaScript. A simple task, such as setting up a website, has figuration, such as what port to run on during debug time.
anything, and security such a high initial cost and so many ways to get lost in this
and identity. process that many developers never get to taste the beauty This is where the curse and blessing of the JavaScript world
of JavaScript. But once you get over the initial gag factor, shows up. There are so many choices, and there’s not one
the possibilities of JavaScript are endless. single correct answer here. For my purposes, I’m going to use
“ejs” as the rendering engine, and “dotenv” as the configura-
Indeed, JavaScript is awesome, or perhaps this is just my tion helper. I don’t claim that these are the best two choices,
opinion. I thought I’d write an article in which I can walk however these are very popular and well-accepted options. I
you through the process of setting up a simple ExpressJS- feel somewhat safe taking a dependency on these node pack-
based Web application that uses TypeScript. In writing this ages. If ever in doubt, many of these node packages are open
article, I want to ensure that I eliminate all cruft, things source; you should see how active their communities are, how
that might distract you, such as UI, or API, or heavy-duty often they merge new pull requests, how many people are
frameworks. You can certainly extend what you’re going to involved in the project, how often they respond to the issues,
read in this article to more complicated projects. I just want how many people have starred that particular GitHub reposi-
to give you a simple starter project that lets you get up and tory. These are some good baselines that you can use to en-
running with ExpressJS and TypeScript. sure that you’re taking dependency on a node module, that’s
somewhere popular, that the teams behind it are responsive
If you wish to reference the code for this article, you can find enough, and that you’ll have a good project lifecycle experi-
it at https://github.com/maliksahil/expressjs-typescript ence with that particular node package.
In my devDependencies, I intend to take a dependence on The first thing you need is an environment file, which in-
TypeScript. In your devDependencies, add the following cludes the basic configuration settings, such as what port
node packages: the application will run on. Because I’ve have taken a de-
pendency on dotnev for this, I simply create a .env file in
"ts-node": "^8.10.2", the root of the project with the following contents:
"tslint": "^6.1.3",
"TypeScript": "^3.9.7" SERVER_PORT=8080
HOST_URL=http://localhost:8080
But wait; there’s more! This alone isn’t enough. When you
start writing code in TypeScript, you take on two new re- It’s customary to add this .env to your .gitignore and check
sponsibilities. TypeScript transpiles into JavaScript, and in a .env.sample file instead. While I’m at it, here’s my full
that JavaScript is what you finally run. You don’t usually .gitignore:
run TypeScript directly. I say “usually” because sometimes
for some helper files, it may be okay to transpile on the fly .cache/
and just run it. For the code you care about, your website, .vscode/
you’ll always statically transpile this code. You don’t want dist/
to transpile it on the fly, because it’d be just too slow. Your node_modules/
first responsibility is all the paraphernalia associated with .env
transpiling. .DS_Store
*.log
There’s one more thing you need to worry about. Now that
you’re using TypeScript, TypeScript will enforce some rules
on you. TypeScript wishes to make sure that you’re using the Listing 1: The devDependencies section of the package.json
correct data types, for example. This is a very good thing "devDependencies": {
because without the appropriate datatypes, you don’t get "@types/dotenv": "^8.2.0",
the correct IntelliSense. Without the correct IntelliSense, "@types/express": "^4.17.7",
"@types/node": "^14.0.27",
you’re more prone to making mistakes. Luckily, there are a "@types/shelljs": "0.7.9",
number of types node packages that give you all these data "shelljs": "0.8.4",
types that you care about. In this project, you’re going to "nodemon": "^2.0.4",
take a dependency on those as well. Given all this, you can "npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
see the full devDependencies in Listing 1. "ts-node": "^8.10.2",
"tslint": "^6.1.3",
Let’s take a moment to understand Listing 1. The various "TypeScript": "^3.9.7"
@types node packages that you see are the type definitions },
that the TypeScript transpiler will depend on, and the IDE,
such as VSCode, will depend on to show the correct Intel-
liSense. Listing 2: The tsconfig.json file
{
The shelljs node package gives you shell-like commands "compilerOptions": {
that you can use in TypeScript. You’ll use this package to "module": "commonjs",
"esModuleInterop": true,
copy transpiled files into a folder from where the Web ap- "target": "es6",
plication can be served. "noImplicitAny": true,
"moduleResolution": "node",
The nodemon node package allows you to restart your ap- "sourceMap": true,
"outDir": "dist",
plication if the underlying files change. I’ll use this for de- "baseUrl": ".",
bug purposes, the idea being, that as I edit a file, the build "paths": {
will automatically run and allow me to see changes in the "*": [
browser. The npm-run-all allows you to run multiple npm "node_modules/*",
scripts in parallel, something you’ll have to do when you "src/types/*"
]
build your site. The rimraf allows you to delete a bunch of }
files easily and you’ll use this to clean your project. The fi- },
nal three, ts-node, tslint, and TypeScript are for TypeScript "include": [
support, as I mentioned above. "src/**/*"
],
"exclude": [
The final section to talk about is the scripts section. I’m not "src/public"
ready to talk about that yet. Let’s finish more of the project ]
first so you have a basic structure in place, and then I’ll }
Next, let’s author the tsconfig.json file. The tsconfig.json Additionally, I’ve also created a “public” folder, where artifacts
file informs the TypesScript transpiler of the various set- that don’t need transpilation can sit. This could be a third-
tings you want it to use. You can see my full tsconfig.json party JavaScript library or framework, such as Bootstrap.
in Listing 2. As you can see in Listing 2, this is a fairly
simple tsconfig.json. I’m targeting commonjs and excluding At this point, my project structure looks like Figure 2.
paths I don’t want compiled. Note that I’ve also given a hint
to include node_modules and src/types, without which the This isn’t a tutorial on ExpressJS and you could replace Ex-
TypeScript transpilation would fail. pressJS with really any JavaScript framework intended to
serve Web applications here. But, let’s understand at a high
Finally, let’s author a tslint.json file. The purpose of the tslint. level how the application is built.
json file is to author all of the linting rules. Even though Type-
Script encourages you to write good code, good is only as good You can see my index.ts in Listing 4. In Listing 4, I’m using
Figure 1: Our basic project as the team or the developer. Additionally, a lot of things are ejs as my view engine and I’m rendering views out of the
structure opinions or arbitrary decisions. For example, what character “views” folder. Additionally, I’m serving static files from the
should you use for a quote? Should it be ‘ or “? Both are cor- public folder, and registering routes from the routes folder.
rect, but it’s important to pick one and stick with it. You can The routes folder serves two routes: index, and about.
specify a lot of rules in tslint.json, but for my purposes, I’ll keep
it simple. You can see my tslint.json in Listing 3. The routes.ts file can be seen in Listing 5. I’m using a con-
cept called barreling, where from index.ts, I can simply
While we’re at it, add a linting script to your package.json import the routes folder. TypeScript looks for a file called
as well, as follows: index.ts in a folder called routes and loads everything ac-
cordingly. This makes it really convenient to separate con-
"lint": cerns into folders as my application grows.
"tslint -c tslint.json -p tsconfig.json"
Finally, my views are rather simple. As can be seen from Fig-
This script runs the linter and throws an error if your writ- ure 2, I have two views, index and about. These match with
ten code breaks one of the linting rules. Imagine if I were what you see in Listing 5, where I’ve defined my routes.
debugging and writing code in parallel, if any time I wrote This could be made dynamic, if you wish. My index.ejs view
poor code, as long as the linter runs inline of my build looks like Listing 6. I’ll omit the about.ejs view for brevity,
process, I’ll be alerted immediately. I’ll show later in this although it’s very similar to index.ejs. Hey, it’s just a simple
article how you can integrate this REPL pipeline. You can Web page that says “About”. You’re welcome to check out
also integrate this as a part of your check-in/branch merge the code in the GitHub repo mentioned above.
rules, but I won’t be covering that in this article.
The partial views are a reusable snippet of ejs views that
I can embed in any other such view. As an example, the
Write Your Application header.ejs is shown here:
So far, you have your configuration settings and your pack-
age dependencies done. You also added one linting script. <h1>Header</h1>
Now, let’s focus on the main project structure. Again, Node- <a href="/">Home</a> |
JS is not very opinionated; you can make this as clean or as <a href="/about">About</a>
messy as you’d like. As I think about creating this project
structure, I have three main things I’d like to achieve. Again, you can make this application a lot more complex if
you wish. This is a great start and you can build from here
• I’d like a src folder where my source code lives. This is using this as a template.
Figure 2: Full project where I write my ExpressJS application in TypeScript.
structure • I’d like a dist folder, where the built version of this Now, let’s focus your attention on the tools folder.
application will live. This is what will eventually run.
• I’d like a tools folder, where I will have helper scripts to You’re going to need some mechanism to build the applica-
facilitate the build process or anything else I might need. tion during debug time. One part of the build is the Type-
"main": "dist/index.js",
This informs the host that when this project is asked to Listing 5: The routes.ts file
run, you should run the dist/index.js file. For instance, if import * as express from "express";
you press F5 in VSCode, this file will run. Of course, this file
doesn’t yet exist; it has to be built. I’ll get there in a mo- export const register = (app: express.Application)
=> {
ment. For now, in your scripts tag, add another script to run // home page
this main entry point: app.get("/", (req: any, res) => {
res.render("index");
"dev": "node .", });
// about page
Now, let’s add a few helper scripts in the scripts section of app.get("/about", (req: any, res) => {
the package.json. You’ll use these helper scripts as building res.render("about");
blocks to facilitate the debugging experience. These can be });
};
seen here:
The copy-assets script runs the copyAssets.ts file using the <head>
<meta charset="utf-8">
ts-node package. If you remember, this file copies the static <title>ExpressJS TypeScript starter template</title>
content that the site depends on and puts it in the dist </head>
folder. The tsc script represents the TypeScript transpiler.
<body>
<%- include('partials/header') %>
The clean script is used to delete older files. The idea is that <h1>Home Page</h1>
as I change code, I want my application to be automatically <%- include('partials/footer') %>
rebuilt and recopied. Before it’s recopied, I want older ap- </body>
plications to be deleted. That’s what I’m using rimraf and
</html>
clean for.
Interested in Moving Now open your favorite browser and visit http://local-
to Azure? host:8080. Your application can be seen running in Figure 3.
CODE Can Help!
This looks great, but the header and footer are HUGE. Let’s
Take advantage of a make them smaller. As the application is running, edit the
FREE hour-long CODE src\public\views\partials\header.ejs and footer.ejs files,
Consulting session
and change the h1 tag to h4. You’ll notice that soon as you
(yes, FREE!) to jumpstart
save the file, the application rebuilds automatically. Now
your organization’s plans
to develop solutions on the
visit your browser and press F5 to see the changes.
Microsoft Azure platform.
For more information, You have a nice REPL (read-eval-print-loop)-based develop-
visit www.codemag.com/ ment environment set up.
consulting or email us Figure 3: Your application is running.
at [email protected].
Summary
In this article, I showed you every bit, corner, and nuance of
writing an ExpressJS and TypeScript-based project. Let me
just say this: As technology is moving forward very fast, the
one thing that suffers is documentation. All of these tech-
nologies are amazing, and once you master them all, you
are incredibly productive. The issue, of course, is mastering
them, because no single article walks you through the very
basics, no single article shows you every single step you
need to take to get a basic application running.
Are you being held back by a legacy application that needs to be modernized? We can help.
We specialize in converting legacy applications to modern technologies. Whether your application
is currently written in Visual Basic, FoxPro, Access, ASP Classic, .NET 1.0, PHP, Delphi…
or something else, we can help.
codemag.com/legacy
832-717-4445 ext. 9 • [email protected]
your Web page and show the user their location based on displayError("Please update your browser
that latitude and longitude. Additional API calls to Google’s to use Geolocation.");
mapping API can give the user step-by-step directions to }
your location. This article shows you how to get started us- });
ing these two powerful APIs.
Display Latitude and Longitude
The getCurrentPosition() method asks the user’s permission
Create HTML to Display Location to retrieve their location. The browser prompts the user to
Information answer with an “OK or “Yes” if they will allow the getCur-
Paul D. Sheriff To begin, build a simple HTML page to display the various rentPosition() method to retrieve their current location. If
[email protected] properties of the geolocation object. Feel free to use your the user answers in the affirmative, the user’s location is
http://www.pdsa.com tool(s) of choice to build an HTML page named index.html retrieved, and the data is placed into a Coordinates object.
and a Web project. You can use Node.js/Express, MVC, Web This Coordinates object is passed to the callback function
Paul has been in the IT
Forms, etc. All you need is a Web server to run the HTML you passed into the getCurrentPosition() method. Within
industry over 33 years.
page and a CDN reference to jQuery. After creating your Web the displayPosition() function is where you extract the lati-
In that time, he has suc-
project and the index.html page, open the index.html file tude, longitude, and other properties. Add the following
cessfully assisted hundreds
of companies architect and add the code shown in Listing 1 into this file. code within the displayPosition() function.
software applications
to solve their toughest Styles function displayPosition(pos) {
business problems. The index.html file references a stylesheet named site.css. let coords = pos.coords;
Paul has been a teacher In this file is where you place some CSS rules to set some
and mentor through margins, padding, and some color. Add a file named site.css $("#timestamp").text(new Date(pos.timestamp));
various mediums such in a styles folder (add this folder if needed) and place the $("#lat").text(coords.latitude);
as video courses, blogs, code shown below into this file. $("#long").text(coords.longitude);
articles, and speaking $("#accuracy").text(coords.accuracy);
engagements at user header, main { padding-left: 2em; } $("#altitude").text(coords.altitude ?? "n/a");
groups and conferences $("#altitudeaccuracy").
around the world. .alert { text(coords.altitudeAccuracy ?? "n/a");
Paul has 26 courses in margin-top: 1em; $("#heading").text(coords.heading ?? "n/a");
the www.pluralsight.com margin-bottom: 1em; $("#speed").text(coords.speed ?? "n/a");
library (http://www.plu- padding: 1em; }
ralsight.com/author/paul- background-color: red;
sheriff) on topics ranging color: white; Try It Out
from JavaScript, Angular,
} Save the changes to all your files and run your Web proj-
MVC, WPF, XML, jQuery,
ect. Your browser prompts you that this Web page is asking
and Bootstrap.
.d-none { display: none; } to know your location. There will be two options: to allow
this page to access the geolocation coordinates or decline
access. For now, go ahead and allow access to see your lati-
Get Latitude and Longitude tude, longitude, and other properties. You should see data
When using the geolocation object, the first thing you appear like the data shown in Figure 1.
should do is check to ensure that the user’s browser sup-
ports the object. After your page loads, check to see if
something other than a null or undefined is returned when
you check the navigator.geolocation property. If a geoloca-
tion object is returned, you can call the getCurrentPosition()
method on that object and pass in the name of a function
to call once the current location has been determined. If a
geolocation object isn’t returned, call a function to display
an error message. Add the code shown below within the
$(document).ready() function.
$(document).ready(function () {
if (navigator.geolocation) {
navigator.geolocation.
getCurrentPosition(displayPosition);
}
else { Figure 1: Display Latitude, Longitude, and Accuracy
Add Error Handling Listing 2: Handle location errors by displaying a specific error message.
You should not assume that the geolocation object will al-
function handleError(error) {
ways work. There are a few things that can go wrong: the let msg = "";
user may not allow access to the geolocation object, the
call to getCurrentPosition() may timeout, the current user’s console.log("error.message = " + error.message);
location may not be able to be determined, and other errors switch (error.code) {
case error.PERMISSION_DENIED:
may occur. In case an error does occur, make sure to set up msg = "User does not want to display location.";
an error message to display on the page. break;
case error.POSITION_UNAVAILABLE:
In the index.html page you created, there is a <div msg = "Can't determine user's location.";
id=”errorArea”> where you place any error messages. This break;
case error.TIMEOUT:
<div> has a style of “alert,” which displays error messages msg = "The request for geolocation info timed out.";
with a red background and white letters. The style of “d- break;
none” is also in the class attribute. This hides the <div> case error.UNKNOWN_ERROR:
until you’re ready to display an error message. Add the fol- msg = "An unknown error occurred.";
break;
lowing code in the displayError() function. }
Property Description
enableHighAccuracy If set to true, informs the device to attempt to obtain a more accurate
position. This can slow down the time it takes to retrieve the coordinates.
timeout The maximum length of time to wait before throwing an exception.
This value is expressed in milliseconds.
maximumAge The maximum age of the last cached position that’s acceptable to return.
This value is expressed in milliseconds. Set to 0 to not allow the device
to cache positions.
Table 1: You may set any or none of the PositionOptions. Figure 2: Create an error area to display error messages
Pass Coordinates to Google Maps Add a function within the <script> tags named displayOn-
Once you have the latitude and longitude from the geoloca- Map() as shown in the code below.
tion object, you have a variety of options on how to display
those coordinates. There are free and paid services you can function displayOnMap() {
use. For example, with Google Maps, Bing Maps, or Open let coords = geoController
<main>
<p>Latitude: <span id="lat"></span></p>
<p>Longitude: <span id="long"></span></p>
Open the styles\site.css file and add a new CSS rule for the
mapArea class. Add the CSS rule shown below to set the width
and height of the <div> where the map is to be embedded.
Figure 3: Google Maps can display any latitude and longitude through the URL.
.mapArea {
width: 90%;
.getPosition().coords; height: 500px;
}
window.location.href =
`https://google.com/maps? Fix the Script Code
q=${coords.latitude}, Remove the $(document).ready() function and replace it
${coords.longitude}`; with a function named initialize().
}
function initialize() {
This code retrieves the GeoLocationPosition object by call- geoController.getCurrentPosition(
ing the getPosition() method in your closure. It then ex- displayPosition, displayError);
tracts the coords property and puts it into a local variable };
named coords. Pass in the latitude and longitude on the
URL line in a format that looks like the following: Locate the displayPosition() function and remove the code
that set the elements you removed from the HTML. Also,
https://google.com/maps?q=36.084391,-86.773550 make a call to a new function named addMap().
function addMarker(location) {
// Create a new marker
location.marker = new google.maps.Marker({
position: new google.maps.LatLng(
location.latitude, location.longitude),
map: map,
title: location.title
});
Instead of using your location to position the embedded let locations = [];
Google Map, let’s set up a fictitious company named “Paul’s
Training Company” located in Brentwood, TN, USA. Add two Create a new function within the closure named createLoca-
private variables within the closure. tions() in which you push as many different literal objects
into the locations array as you want to display on the map.
let map = null;
function createLocations() {
let location = { locations.push({
"latitude": 36.036020, "latitude": 36.036020,
"longitude": -86.787600, "longitude": -86.787600,
"title": "Paul's Training Company", "title": "Paul's Training Company",
"marker": null "marker": null
}; });
locations.push({
The map property is going to hold a reference to the Google "latitude": 36.0339689,
Map object. The location property is a literal object with "longitude": -86.8058154,
the latitude, longitude, and the title of the location. The "title": "Mere Bulles",
marker property is currently set to null but is going to be "marker": null
set by code you write very soon. });
}
Because you’re not using the call to the geolocation ob-
ject to get the coordinates, just call the addMap() function You need to call this new function from the initialize() func-
passing in the location variable. Modify the initialize() tion, then loop through each item in the locations array
function in your closure to look like the following code and pass each item to the addMarker() method. Modify the
snippet. initialize() function to look like the following.
// Rest of the code Add a new function to your closure named addDirections().
} This function creates an instance of a google.maps.Di-
rectionsService class and an instance of google.maps.
A LatLngBounds class has an extend() method to which you DirectionsRenderer class. Call the route() method on the
pass in a LatLng class. The LatLng class contains two proper- DirectionsService class, passing in a literal object with the
ties lat and lng. Your addMarker() function creates a LatLng
object from the latitude and longitude in your map definition
object. Call the extend() method after calling the addMark-
er() function within the loop in the initialize() function.
Figure 5: Google Maps can add a line showing how to Figure 6: Google Maps can add directions in text format
travel from point A to point B. between two points.
Try It Out
Save your changes to this page and redraw the Web page.
You should now see a panel with text directions just below
your map. If you don’t see the text directions, check the Figure 7: Add an informational window to provide a better
console window for any error messages. description of the location
What’s Wrong with the Options API? In addition, the way that properties are made reactive is an ad-
First of all, nothing’s wrong with the options API. If you’re ditional piece of magic. When the members are returned from
happy with the Options API, stay with it. But I hope you can the data function, Vue wraps them (often using Proxy objects)
see why the Composition API is a better way to do it. When to be able to know when the object changes. Of course, this
I first started using Vue, I really liked how they used an can be confusing if you try to replace the object. For example:
anonymous object to set up a component. It was easy and
felt natural. The longer I used it, the more it started to feel export default {
weird. Its reliance on the manipulating the this pointer was data: () => {
hiding some of the magic of how Vue works. return {
Shawn Wildermuth name: "Shawn",
[email protected] For example: items: []
wildermuth.com };
twitter.com/shawnwildermut export default { },
data: () => { mounted: async function () {
Shawn Wildermuth has
return { this.load()
been tinkering with com-
puters and software since name: "Shawn", .then(result => {
he got a Vic-20 back in the }; // breaks reactivity
early ’80s. As a Microsoft }, this.items = result.data;
MVP since 2003, he’s also methods: { });
involved with Microsoft save: function () { }
as an ASP.NET Insider and alert(`Name: ${this.name}`); // MAGIC };
ClientDev Insider. He’s },
the author of over twenty }, This is one of the most common problems with Vue. Al-
Pluralsight courses, written mounted: async function () { though these can be gotten around pretty simply, it’s an im-
eight books, an interna- this.name = "Shawn's Name'; // MAGIC pediment to learning how Vue works. Nothing is as frustrat-
tional conference speaker, } ing as a bug that doesn’t work and doesn’t throw an error.
and one of the Wilder }; These issues often end up happening with the Options API.
Minds. You can reach
him at his blog at Because much of the work is done when the functions you Lastly, there’s a big issue with composing your components.
http://wildermuth.com. define (e.g., save/mounted) are called, you have to really Being able to use shared functionality was difficult with the
He’s also making his first, understand how the this pointer works. For example, can Options API. Loading objects or methods that you then used
feature-length documentary
you tell me without compiling if this would have worked? in the component was hindered by the nature of the Options
about software developers
object. To combat that, Vue uses the notion of mixins. For ex-
today called “Hello World:
mounted: async function () { ample, you could create a mixin to extend a component like so:
The Film.” You can see
this.load()
more about it at
http://helloworldfilm.com. .then(function() { import axios from "axios";
this.name = "Shawn's Done";
}); export default {
} data: function () {
return {
No, it wouldn’t. The reason is that the mounted function’s this items: []
member has the Vue properties added. When you create a new };
nested function (e.g., in the call to then()), it creates a new },
scope and therefore a new this member. You’d have to remem-
ber to fix it by either using an Arrow function (e.g., () => ) methods: {
or wrapping the this pointer. For example, this small fix load: async function() {
works: let url =
"https://restcountries.eu/rest/v2/all";
mounted: async function () { let result = await axios.get(url)
this.load() this.items.splice(0,
.then(() => { // The fix this.items.length,
this.name = "Shawn's Done"; ...result.data);
}); },
} removeItem: function (item) {
let index = this.items.indexOf(item);
But that requires quite a lot of finesse to get right. What if (index > -1) {
feels simple and right at first, turns into a bit of a headache. this.items.splice(index, 1);
Note that the mixin looks a lot like the Vue Options API. It Instead of just assigning the value in the return, create it
simply does a merge of the objects to allow you to add on with a local variable inside the setup. Why would you? Be-
to specific components. You use a mixin by specifying it in cause of JavaScript closures. Let’s extend this and make a
the component: function that will be used in the markup:
import dataService from "./dataService.mixin"; export default {
setup() {
export default {
mixins: [dataService], const name = "Shawn";
...
function save() {
The biggest issue with mixins is that you can’t protect or alert(`Name: ${name}`);
easily know about name collision. It becomes trial and error };
to find out that a mixin was changed to use the same prop-
erty or method of the component (or other mixins). Again, return {
the magic is hidden behind the veneer of Vue and it makes name,
debugging more difficult. save
};
In the light of these limitations, the Composition API was born. },
};
What’s the Composition API? The function can access the name because they’re in the
Now that I’ve discussed the limitations of the Options API, same scope. This is the magic of the Composition API. No
let me introduce you to the Composition API. If you’re still magic, just JavaScript. What you can do with this pattern
using Vue 2, you can still use the Composition API. To get can become much more complex, but the basis of it all is
started, you need to import the composition API library. just the closures. That’s it.
First add it to your npm package:
In this example, the name is never changed. For Vue to be
> npm i @vue/composition-api --save able to handle binding, it needs to know about any chang-
es to the name. In this example, if you change the code to
To enable the composition API, you simply have to register change the name in save(), it won’t be reflected in the UI:
the composition API (usually in the main.js/ts):
export default {
import Vue from 'vue' setup() {
import VueCompositionAPI
from '@vue/composition-api' const name = "Shawn";
Vue.use(VueCompositionAPI) function save() {
name = name + " saved"; // name changed
Now that you’ve enabled it, let’s take a look at the first Com- alert(`Name: ${name}`);
position API component. At first, the look of a component };
looks similar:
return {
export default { name,
setup() { save
return { };
}; },
}, };
};
Reactivity
It still starts with an anonymous object but the only mem- When you return the object of the bindable object, Vue can
ber (so far) is a method called setup. Inside the setup, see changes to the specific properties (the object is observed
you’ll return any data you need. This is very much like the for changes). But because you’re really assigning a new name
function-type of data property in the Options API: in the Save method, there’s no way for Vue to know it’s been
changed. It’s still seeing the old name. To address this, Vue
export default { uses two methods of reactivity: ref and reactive wrappers.
setup() {
To make the name reactive, you can just wrap it with a ref object:
const name = "Shawn";
import { ref } from "@vue/composition-api";
return {
The name object is now wrapped with a ref object. This is a setup() {
simple reactive that provides a property called value that
represents the actual value. You’re now assigning and re- const name = ref("Shawn");
porting the name using the value property. Because it’s us-
ing a ref wrapper, the changes will be notified to the user watch(() => name,
interface. This is an important concept, as you’re surfacing (before, after) => {
some of the magic so that it’s more obvious what’s happen- console.log("name changes");
ing here. });
This works well with primitive objects, but for objects with return {
their own state (e.g., your classes or arrays), changes to the name
value aren’t enough. What you really need is to use a proxy };
object so that any changes that happen inside functions on },
the object cause notifications of those changes.
The watch function takes two parameters: a callback to re-
import { ref, reactive } turn the data to watch, and a callback to be called when the
from "@vue/composition-api"; change happens. It supplies the before and after values in
case you need to use them.
export default {
setup() { Alternatively, you can use watchEffect, which watches for
any changes in the reactive objects referred to in the com-
const name = ref("Shawn"); ponent. It takes just a single callback:
const items = reactive([]);
watchEffect(() => {
function save () { console.log("Ch..ch...ch...changes.");
// Change Array });
items.splice(0,items.length);
name.value = name.value + " saved"; Now you can use reactivity to not only make the markup
alert(`Name: ${name.value}`); react to changes, but also to have your own code react to
}; those same changes.
// Use Load from factory function return {
onMounted(async () => await load()); load, // from import
removeItem, // from import
function save () { name,
alert(`Name: ${this.name}`); save,
}; items // from import
};
return { },
load, // from factory function };
removeItem, // from factory function
name, If you’re already using Vuex, you can still use it in the Com-
save, position API. Vuex is more complex, but it does add some
items // from factory function strictness to the read/write processes (only allowing changes
}; in mutations). If you haven’t worked with Vuex, I cover it in
}, the January/February 2020 issue of CODE Magazine (https://
}; www.codemag.com/Article/2001051/Vuex-State-Manage-
ment-Simplified-in-Vue.js). Assuming you have a Vuex store
This pattern allows you to create factory functions to inject created, the wiring up is different. There are no more helpers,
the functionality you need in your component. Remember, in as the magic that they do can be handled pretty simply:
this pattern, you’re getting a new instance of these items on
every call (which is often what you want). But if you wanted import { ref,
to share the data (like showing the same data on different reactive,
forms), you could always use a simpler instance pattern: computed,
onMounted }
import axios from "axios"; from "@vue/composition-api";
import store from "./store";
export let items = [];
export default {
export async function load() { setup() {
But because the properties aren’t added to the magic this point- Using Composition API in Vue 3
er, how do you use the properties in setup? You can get access If you’re using Vue 3, you don’t need to opt-into the Compo-
to the properties by adding the optional parameter to setup: sition API. It’s defaulted in the set up of a new project. The
@vue/composition-api library is only used for Vue 2 projects.
setup(props) { The real change for Vue 3 is that when you need to import
watch(() => props.isBusy, Composition APIs, you need to get them directly from Vue:
(b,a) => {
console.log(`isBusy Changed`); import { ref,
}); reactive,
} onMounted,
import {
defineComponent, Over 25 search options
reactive,
onMounted,
including:
ref • efficient multithreaded search
} from "vue"; • easy multicolor hit-highlighting
import Customer from "@/models/Customer"; • forensics options like credit
card search
export default defineComponent({
name: "App",
setup() {
... Developers:
} • SDKs for Windows, Linux,
});
macOS
• Cross-platform APIs for
.
Additionally, you can use types in your set up:
C++, Java and NET with
const customers =
reactive([] as Array<Customer>);
. .
NET Standard / NET Core
const customer = ref(new Customer()); • FAQs on faceted search,
const isBusy = ref(false); granular data classification,
const message = ref(""); Azure and more
In these examples, the variables are inferred as types (for
example, the Customers object is Reactive<Customer[]>). In
addition, the API is typed so it will lower your chances to
pass in the wrong data. Of course, additionally, IntelliSense
is a big benefit if you’re using TypeScript (especially in Vi-
Visit dtSearch.com for
sual Studio or VS Code), as seen in Figure 1. • hundreds of reviews and
case studies
Where Are We? • fully-functional enterprise
Whether you’re a veteran Vue developer or brand new, get-
ting used to the Composition API is going to require you to
and developer evaluations
change your mindset. The move from convention to some-
thing that’s more explicit may be uncomfortable, but I’ve The Smart Choice for Text
found that I like the new model a lot better. I spend less
time scratching my head about what’s happening with func-
Retrieval® since 1991
tion scope and trying to remember when I can and can’t use
the arrow functions. I hope I’ve convinced you. 1-800-IT-FINDS
Shawn Wildermuth
www.dtSearch.com
Introduction to the Go
Programming Language
Go (aka Golang) is one of the fastest growing programming languages. It’s an open-source language released by Google in
2009 and created by Ken Thompson (designer and creator of UNIX and C), Rob Pike (co-creator of UTF 8 and UNIX format), and
Robert Griesemer. It’s a multi-purpose programming language specifically designed to build scalable and faster applications.
Although Go has been around for quite a while now, it To run the helloworld.go, you can first build the program
didn’t manage to get wide adoption by developers until using the go tool with the build command:
more recently due to the proliferation of cloud comput-
ing and microservices. Today, Go has been widely used $ go build helloworld.go
by major companies such as Google, Dropbox, Uber, and
Dailymotion. A binary will then be created. You can now run the binary
and see the output:
In this article, I’ll walk you through the language and dive
into some areas where Go shines. By the end of this ar- $ ./helloworld
Wei-Meng Lee ticle, you should have a pretty solid feel of Go and be on Hello, world!
[email protected] your way to writing some cool Go packages.
http://www.learn2develop.net Alternatively, you can also build and run the program using
@weimenglee the run command:
Getting Started with Go
Wei-Meng Lee is a technolo-
gist and founder of Devel- Installing Go on your computer is straight-forward—go to $ go run helloworld.go
oper Learning Solutions https://golang.org/dl/ and download the installer for the Hello, world!
(www.learn2develop.net), OS you are using (see Figure 1).
a technology company spe- You can also use the built-in println() and print() function
cializing in hands-on train- You can use your favorite code editor to write Go code. I use for printing purposes.
ing on the latest technolo- Visual Studio Code.
gies. Wei-Meng has many Variables
years of training experiences Hello World! There are a couple of ways to declare variables in Go. To
and his training courses In the spirit of adhering to tradition, let’s create a text file declare a variable explicitly, you use the var keyword:
place special emphasis named helloworld.go and populate it with the following
on the learning-by-doing statements: var num1 = 5 // type inferred
approach. His hands-on var num2 int = 6 // explicitly typed
approach to learning package main var rates float32 = 4.5 // declare as float32
programming makes // and initialize
understanding the subject import "fmt"
much easier than read- var raining bool = false // declare as bool
ing books, tutorials, and func main() { // and initialize
documentation. His name
fmt.Println("Hello, world!")
regularly appears in online
} Notice that you can either explicitly specify the type of
and print publications such
variable, or let the compiler infer it for you. When you
as DevX.com, MobiForge.
com, and CODE Magazine. The first line indicates the name of this package, which is are declaring a variable and initializing it, you should use
main. Packages are used in Go to organize and reuse code. type inference. Otherwise, you need to specify the type
Within this main package, you have the main() function, explicitly:
which is the function to call when you start your program.
Note that you also import another package called fmt, var str string // declare as string
which is a package that implements formatted I/O. This
package contains functions (e.g., Println) that allow you Variables declared without initialization are zero-valued.
to print output to the console, similar to C’s printf() and For example, str above would have an initial value of “” and
scanf() functions. an integer variable has a value of 0.
Here’s another example where you can declare and initialize The following sections discuss each of these in more detail.
multiple variables:
Arrays
var ( In Go, an array has fixed size. That is, once an array is de-
age = 25 clared, its size cannot be changed. The following shows
name = "Samuel" some examples of declaring arrays of specific sizes:
)
var nums [5] int // int array of 5 items
String Interpolation fmt.Println(nums) // [0 0 0 0 0]
One of the common things you do in programming is print-
ing out the values of variables in a string. Consider the fol- var names [3] string // string array of 3
lowing declarations: // items
fmt.Println(names) // [ ]
var num1 = 5
var rates float32 = 4.5 var ended [3] bool // bool array of 3 items
fmt.Println(ended) // [false false false]
Suppose you want to print out the values of these two vari-
ables in a string. To do that, you need to convert the two Array elements are zero-based, and you can access them in-
numeric variables using the strconv package: dividually and also assign values to them:
y := x
fmt.Println(x) // [0 0]
fmt.Println(y) // [0 0]
y = append(x,5)
fmt.Println(x) // [0 0]
fmt.Println(y) // [0 0 5]
In the above code snippet, original is a slice of capacity To extract the first two items, you can use the following slicing:
four. After you assigned original to other, other is now a
reference to original (see the top of Figure 2). b := c[0:2]
fmt.Println(b) // [iOS Android]
Now, when you make changes to the third element in other
like this: The result of the slicing (b) is a slice. You can print the ca-
pacity of b using the cap() function:
other[2] = 8
fmt.Println(cap(b)) // 3
Both slices now print the same values (see also the middle
of Figure 2): Observe that the capacity of b assumes the capacity of the un-
derlying array - c. You can change the capacity of the slice b,
fmt.Println(original) // [1 2 8 4] by specifying the capacity as the third argument in the slicing:
fmt.Println(other) // [1 2 8 4]
b = c[0:2:2]
If you append an item to original and then assign it to other: fmt.Println(b) // [iOS Android]
fmt.Println(cap(b)) // 2
other = append(original, 5)
Maps
Then other now points to a new slice (as it has exceeded Besides array, another essential data structure is a dictionary.
its capacity of four), as shown in the bottom of Figure 2. In Go, this is known as a map, which implements a hash table.
So when you now make changes to other, original won’t The following statement declares a map type called heights:
be affected:
var heights map[string] int
other[2] = 9
fmt.Println(other) // [1 2 9 4 5] The following statement initializes the map using the
fmt.Println(original) // [1 2 8 4] make() function:
Consider another example, where you now have a slice of heights = make(map [string] int)
two elements but with a capacity of four:
The following statement declares and initializes an empty map:
x := make([] int, 2, 4)
Figure 3: The x and y slices fmt.Println(x) // [0 0] weights := map[string] float32 {}
The following statement adds a new key/value pair to the Here is another example of creating a new instance of the
heights map: Point struct:
To check whether a key exists in the map, use the following pt2.X = 22
code snippet: fmt.Println(pt1) // {2 3}
fmt.Println(pt2) // {22 3}
if value, ok := heights["Peter"]; ok {
fmt.Println(value)
} else {
Decision-Making and
fmt.Println("Key does not exists") Looping Constructs
} Go’s decision-making statements are very similar to other
languages. It supports the standard if-else statement and
If the key exists, the ok variable will be set to true; other- switch statement, but surprisingly, no ternary statement.
wise, it will be set to false. You can also iterate through a For looping, there’s only one looping construct: the for loop.
map using the for loop together with the range keyword:
The following sections will discuss these in more detail.
// iterating over a map
for k, v := range heights { If-else
fmt.Println(k,v) Decision making in Go is very similar to other languages:
}
if true {
Structs fmt.Println(true)
Go doesn’t have classes, but it supports structs. The follow- } else {
ing shows the Point struct containing two members: fmt.Println(false)
}
type Point struct {
X float64 Interestingly, there’s no ternary operator in Go. However,
Y float64 the if statement allows you to have two expressions in it:
} one assignment and one condition. Consider the following:
To invoke the anonymous function, you call i the way you Consider the following example:
call a normal function, like this:
package main
fmt.Println(i()) // 5
import (
"fmt"
Closures
"time"
Anonymous functions are very useful when implementing
)
closures. A closure is a function that references variables
from outside its body. Closures allow you to pass in func- func say(s string, times int) {
tions as arguments into functions. To understand closure, for i := 0; i < times; i++ {
it’s useful to see a concrete example. time.Sleep(100 * time.Millisecond)
fmt.Println(i, s)
Most programming languages that support closures (AKA lamb- }
da functions) come with the predefined filter(), map(), and }
reduce() functions. However, Go doesn’t come with these pre-
func main() {
defined functions. So let’s now implement the filter() function
go say("Hello", 3)
in Go using closures. Consider the following filter() function: go say("World", 2)
Channels i = 0
Goroutines are executed independently of one another. total := 0
But they can communicate with one another through pipes for i<parts {
known as channels. In Go, channels are the pipes that con- partialSum := <-c // read from channel
nect concurrent goroutines. You can send values into chan- fmt.Println("Partial Sum: ", partialSum)
nels from one goroutine and receive those values in another total += partialSum
goroutine. To understand the usefulness of channels, con- i += 1
sider the following example. Suppose you have a function }
named sum() that sums up an array of integer values: fmt.Println("Total: " , total)
func sum(s []int, c chan int) { Each value in the channel represents the partial sum of the
sum := 0 values in each array. It’s important to know that when you
for _, v := range s { send a value into a channel, the goroutine is blocked until
sum += v the value is received by another function/goroutine. Like-
} wise, when you’re reading a value from a channel, your code
c <- sum is blocked until the data is read from the channel. In the
} event that the goroutines are taking a long time to sum up,
the above code snippet will block until all the partial sums
Notice that the function has a second parameter: are retrieved. Listing 1 shows a complete program where you
can simulate the sum() function summing up 1000 numbers.
func sum(s []int, c chan int) {
The chan keyword represents a channel, and in this example, it’s Go Packages and Modules
a channel of type int. When the numbers in the array have been Go uses the concept of packages to better organize code for
summed up, the sum is written to the channel via this syntax: reusability and readability. So far, you’ve seen how to use
some of the built-in packages like fmt, strconv, math, and
c <- sum time in your Go application. In this section, you‘ll dive into
the topic of packages and modules in more detail. You will $HOME
also learn how to create your own packages and make them |__my_app
available to fellow developers for use. |__helloworld.go
• Both files are in the same directory The above creates a module named stringmod, with a sub-
• Both packages have the same package name (main) directory named strings. The idea is to group related func-
• One of the files has a main() function tionalities into directories so as to logically group them
$HOME The “go mod init” command creates a go.mod file in the
|__stringmod stringmod directory:
|__strings
|__strings.go $HOME
|__quotes |__stringmod
|__quotes.go |__go.mod
|__strings
Populate the strings.go file with the following: |__strings.go
|__quotes
package strings |__quotes.go
import ( It lists all the packages required by the packages inside the
"github.com/hackebrot/turtle" module. There’s one additional file created: go.sum. This
) file contains the expected cryptographic checksums of the
content of specific module versions. It looks like this:
func GetEmoji(name string) string {
emoji, ok := turtle.Emojis[name] github.com/hackebrot/turtle v0.1.0 h1:cmS72nZuooIARtgix6IRPvm
if !ok { w8r4u8olEZW02Q3DB8YQ=
return "" github.com/hackebrot/turtle v0.1.0/go.mod
} h1:vDjX4rgnTSlvROhwGbE2GiB43F/l/8V5TXoRJL2cYTs=
return emoji.Char
} Using the Module
With the module created, let’s try to import it into another
Observe that the quotes package has a dependency on an package and use it. Add a new file named main.go in the
external package: github.com/hackebrot/turtle. stringmod folder:
func main() { • Src: contains the source code of packages that you
o, e := str.CountOddEven("12345") have installed in your computer
fmt.Println(o,e) // 3 2 • Bin: contains the binary executables of Go applica-
tions that have the main package (and therefore con-
fmt.Println(qt.GetEmoji("turtle")) tains the main() function).
} • Pkg: contains the non-executable packages. These
packages are typically imported by other applications.
Finally, to run the program type the following command in
Terminal:
Summary
$ cd ~/stringmod By now, you should have a pretty good feel for the Go lan-
$ go run main.go guage. Syntax wise, it’s close to C and should be very easy
🐢
3 2 for developers to pick up. Goroutines is one big feature of
the language, which should make it a breeze to create multi-
threaded server-side apps. Hopefully, this article makes
Publishing the Module your learning journey much easier and fun!
So far, your module has been created and tested correctly
to run locally on your computer. To share it with the world, Wei-Meng Lee
you simply need to publish it to an online repository, like
TAKE
AN HOUR
ON US!
Does your team lack the technical knowledge or the resources to start new software development projects,
or keep existing projects moving forward? CODE Consulting has top-tier developers available to fill in
the technical skills and manpower gaps to make your projects successful. With in-depth experience in .NET,
.NET Core, web development, Azure, custom apps for iOS and Android and more, CODE Consulting can
get your software project back on track.
Contact us today for a free 1-hour consultation to see how we can help you succeed.
codemag.com/OneHourConsulting
832-717-4445 ext. 9 • [email protected]
infrastructure for packaging and distribution. This means The SDK dependence is both a blessing and a curse: Be-
it’s quick and easy to build tools that you can share either cause the .NET Core Runtime is guaranteed to be installed,
publicly with the world or privately with yourself or your binaries of your .NET Core Tool can be very small and only
onsite team. consist of application-specific files. But the .NET SDK must
exist on the target computer and this SDK install is neither
small, nor something that a typical, non-development user
What’s a .NET Core Tool? already has installed.
When you break down a .NET Core Tool into its simplest
terms, you end up with this simple statement: Global and Local .NET Core Tools
Rick Strahl .NET Core Tools can be installed either as a global or local
www.west-wind.com “A .NET Core Tool is a glorified .NET Core application that tool. Global tools are installed in a central location on the
[email protected] can be quickly and easily shared and installed via NuGet.” local computer and mapped on the global path, so they are
globally accessible. Local tools are installed into a specific
Rick Strahl is president of
The idea behind a .NET Core Tool is to make it easy to build, folder and only accessible from there. They’re essentially
West Wind Technologies in
publish, and consume executable tools in the same way you project-specific and they-re useful for build systems that
Maui, Hawaii. The company
can create NuGet packages for .NET and .NET Core components. need to encapsulate tools as part of a build process or Con-
specializes in Web and
distributed application tinuous Integration (CI).
development and tools, Although the original idea was to build tools to aid as part
with focus on Windows of the build and development process, this platform really In this article, I focus on the usage for global tools and the
Server Products, .NET, offers a much wider scope because you can publish and sharing aspects of .NET Core Tools as general-purpose utili-
Visual Studio, and Visual share any .NET Core executable application. This includes ties using the global -g command line switch. Everything
FoxPro. Rick is the author servers that run full ASP.NET Core applications or services except the install location and global path access also ap-
of West Wind Web Connec- and even .NET Core desktop applications. plies to local tools in the examples.
tion, West Wind Web Store,
and West Wind HTML Help Why Use Dotnet Tools? Careful: Security of .NET Core Tools
Builder. He’s also a C# MVP, Although the idea behind .NET Core Tools isn’t anything new, Because .NET Cire Tools are executables installed from a re-
a frequent contributor to this tooling does provide several benefits to developers and mote source and because there’s no validation process for
magazines and books, a the entire .NET Core ecosystem. The big selling points are: published tools, it’s important to understand that there is
frequent speaker at inter- a potential security risk to your computer. The code that
national developer confer- • Easy to use comes down can execute locally on your system and has ac-
ences, and the co-publisher • Single command installs. Example: dotnet tool cess to your local resources when you run the tool.
of CODE Magazine. install -g LiveReloadServer
• Global path access to run command: LiveReload- Be sure you:
Server --help
• Easy to build • Trust the publisher of the tool.
• Uses standard .NET Core projects • Verify that the tool has reviewable source code avail-
• Uses existing NuGet infrastructure able in a repository.
• Nothing new to learn—works with existing tech • Check for issues on the repository.
• Configured via standard .csproj settings
• Sharing Be careful and know the risks!
• Can be easily shared
• Can reach a large number of users via NuGet To be fair, the same cautions apply to NuGet packages because
• Quickly published and available those too can execute any code contained in the package or
• No explicit package validation in a constructor and there’s not much concern around that.
• Community
• Ease of use and shareability promotes creation of
tools
• Shared content helps build community .NET Core Tools install and run on
your local computer, but they’re not
On the flip side, there’s a big prerequisite to using a .NET
Core Tool:
validated in the NuGet Package Store,
so there’s a potential security risk.
• The .NET Core SDK is required to install a .NET Core Tool
42 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
There’s Nothing New Under the Sun! .NET Core Tool or Platform-Specific Binary?
“Did you just describe NPM?” .NET Core supports creating executable binaries for every
platform that it supports. But each platform requires a cus-
Yup. .NET Core Tools are very much like NPM for .NET Core. tom executable launcher and runtime dependencies to run.
It takes quite a bit of extra effort to create these separate
If all this looks familiar from Node,js and NPM—you’re right. build targets and distribute each one.
The idea of shared tools isn’t new by any means and follows
various other development platforms and their package It’s possible to create standalone executables for each plat-
managers. But for .NET to easily publish and share binary form using either a pre-installed .NET Core runtime installa-
executable tools in a cross-platform manner is relatively tion or a fully self-contained executable that can contain all
new and opens up the reach of small and useful tools that the required runtime files in addition to the files that your
otherwise would never be shared. application needs to run. Self-contained applications are
great for self-reliance and predictable behavior, but they’re
What Can You Use .NET Core Tools For? terribly large, as the .NET Core base runtimes make up a
Although .NET Core Tools were initially designed to provide minimum of 70MB of distribution size.
development time helper tools, they’re just plain .NET Core
executables that can do anything that a .NET Core execut- A fully self-contained application is useful and sometimes
able can do. This means you can use it for all sorts of things required. If you’re building an end user tool or application,
that might not be directly developer related. a self-contained application that has everything it needs
included is usually a better call. But if you’re building de-
Here are a few general use cases addressed by .NET Core Tools: veloper tools, the lightweight and universal .NET Core Tool Source Code on GitHub
distribution experience is often preferable.
You can check out the full
• Build and Development Tools: There are many tools
MagicWindBall project
that follow the original design goal for creating proj- The advantage of building a .NET Core Tool is that it’s not for this article as well as slides
ect helpers that make development tasks easier or fa- platform-specific. Like a NuGet component, a .NET Core and additional content
cilitate external but related development operations. Tool is distributed as a NuGet package that contains only the on the GitHub site. Go to:
For example, tools like EF migration commands in dot- compiled .NET assemblies. There’s no launching executable https://tinyurl.com/dotnettoolsCode
net ef, dotnet watch run, the user secrets manager packaged. Because .NET Core Tools rely on an SDK installa-
and dotnet watch are all .NET Core Tools that fit this tion to run, the runtime is guaranteed to be there. If dotnet
bill. There are many tools available in this category. tool can run on the computer, so can your .NET Core Tool.
• Generic Command Line Tools: If you need to build
some complex command line helpers that work on sce- This means that you can build a single, relatively small
narios that are more complex than what you reason- NuGet package as a .NET Core Tool and it will work on all
ably want to do in PowerShell or Bash, a tool can fit supported .NET Core platforms, assuming your code is writ-
that niche nicely. Because these tools can be shared ten to otherwise use platform-agnostic features. That’s
and installed easily and are generally very small, they cool: The .NET Core Tool provides you with cross-platform
make a good fit for beyond scripting scenarios. functionality without having to build and maintain multiple
• Local Servers: .NET Core makes it easy to build server platform-specific loaders and it keeps the deployment size
applications and it’s easy to create self-contained Web very small.
Server or Services applications. Whether it’s running
a Web application locally for testing, or whether you
have some internal application that maybe is a hybrid Creating and Using .NET Core Tools
using both a Web interface and a desktop application Enough abstract talk! Let’s jump in and see how you can:
in mixed mode, a .NET Core Tool makes it easy to pro-
vide this. It’s very powerful to be able to create small • Build a .NET Core Tool package for distribution
and easily shareable, self-contained Web and server • Publish a .NET Core Tool package
applications. I’ll show a couple of examples of this • Consume a .NET Core Tool package
later.
• Desktop Applications: Although Microsoft’s official Create a .NET Core Tool Step-by-Step
documentation claims that .NET Core Tool is meant for Let’s create a very simple project called MagicWindBall that
console applications, it turns out that you can also predicts wind conditions for the day. It’s a play on the words
create .NET Core WinForms and WPF applications and of Magic Eightball, which is a fake fortune telling device and
package them as tools too. But they are Windows-only. I’m hijacking the idea to tell me my wind fortunes.
Locating Available .NET Core Tools Start by creating a .NET Core Console project. I’ll use the
One of the reasons that .NET Core Tools aren’t so widely used dotnet command line tooling, but you can also use Visual
that it’s not that easy to find them. Until very recently, you Studio (or Rider, etc.) to create a new .NET Core Console
weren’t even able to search the NuGet Site specifically for project.
tools but that was recently fixed with new search filters.
From the command line, start by creating a new folder with
There are a couple of other places you can check for tools: the Project name, and then create a project in that folder:
• Nate McMaster has a GitHub repo with a list of many mkdir MagicWindBall
.NET Core Tools at https://tinyurl.com/natetoollist cd MagicWindBall
• The ToolGet Site searches NuGet with a .NET Core Tool dotnet new console
filter at https://tinyurl.com/toolget code .
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 43
This creates a new project MagicWindBall.csproj that you
can open in Visual Studio or Visual Studio Code. I’ll use VS .NET Core Tools use the existing
Code here, as shown in Figure 1, which makes it easy to .NET tool infrastructure for creation,
open the projects from a folder via the code . command.
publishing, and installing tools.
This project is very simple, with an imaginary wind forecast
generator that randomly displays a string from a list of pre-
defined wind condition strings. Make It a .NET Core Tool
You now have a plain .NET Core Console application. To turn this
The code is along the lines of Listing 1 (full code on GitHub into a .NET Core Tool, add a few specific settings to the project
at https://tinyurl.com/MagicWindBall). file. At minimum, you need to add a few .NET Core Tool-specific
settings to the project. Add <PackAsTool>, provide a name, and
First, let’s make sure the code works as a regular Console set up the project to build as a NuGet package, as shown in
application. Open a Terminal in the project folder and do: Listing 2.
dotnet run With these flags in place, you can now build the project and gen-
erate the .NET Core Tool NuGet Package into the ./nupkg folder:
In Figure 1, I use the built-in Terminal in VS Code to test
the application. dotnet build -c Release
Figure 1: Opening and running the Console project in Visual Studio Code.
44 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
Listing 1: The MagicWindBall Sample Tool
static void Main(string[] args) ConsoleColor.DarkYellow);
{ break;
WriteWrappedHeader("Magic WindBall"); case 1:
WriteLine("Light Wind - Pray for wind.",
Console.WriteLine(); ConsoleColor.DarkCyan);
break;
Write("thinking.", ConsoleColor.Cyan); case 2:
Wait(500); WriteLine("Light Breeze - Sucker wind.",
ConsoleColor.DarkGreen);
Write(" consulting the stars.", ConsoleColor.Yellow); break;
Wait(1000); case 3:
Write(".", ConsoleColor.Yellow); WriteLine("Breezy- Wake up and get ready.",
ConsoleColor.Green);
Write(" guessing some more.", ConsoleColor.Cyan); break;
Wait(1000); case 4:
Write(".", ConsoleColor.Cyan); WriteLine("Windy- Why are you still here?",
ConsoleColor.Yellow);
Console.WriteLine('\n'); break;
case 5:
var rnd = new Random(DateTime.UtcNow.Millisecond); WriteLine("Super Nuker– Batten down the hatches",
var val = rnd.Next(6); ConsoleColor.Red);
break;
Console.WriteLine("Wind today be:"); default:
WriteLine("Roll the Dice- Coming in waves.");
switch (val) break;
{ }
case 0: Console.WriteLine();
WriteLine("No Wind - Skunked again.", }
For public tools that come from the default cloud based
NuGet package store, you use:
Et voila! You’ve just installed the .NET Core Tool locally and
you can now run the tool simply by typing magicwindball Figure 2: The .NET Core Tool NuGet Package in the NuGet Package Explorer.
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 45
into the Terminal from anywhere on your computer. Figure for a .NET Component. You use NuGet publish or you can also
3 shows building, installing, and running the tool in a Ter- use the NuGet Package Explorer shown earlier in Figure 2.
minal window.
Here’s a build, sign, and publish PowerShell script (the full
Publishing to NuGet script is here: https://tinyurl.com/SnippetConverter):
.NET Core Tools are published as NuGet packages and use the
same exact mechanism you use to publish a NuGet package dotnet build -c Release
if ($len -gt 0) {
nuget sign ".\nupkg\$filename" `
-CertificateSubject "West Wind " `
-timestamper "..."
nuget push ".\nupkg\$filename"
-source nuget.org
}
You can now install and run the component from the NuGet
Package Store. Figure 5 shows the install and run sequence.
If you need to update the .NET Core Tool, make your code
changes and increment the version number of the project
then simply re-publish to NuGet. A new package with the
new version number is created and pushed, which then be-
comes available on NuGet. You can then use dotnet tool
update -g dotnet-magicwindball to update the local tool
installation to the updated version.
46 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
folder and is then globally available using the <Command- Figure 7 shows what that looks like inside of WSL. You can
Name> specified by the project. Figure 6 shows the launcher do the same on an actual Linux or Mac computer. Figure 8
in the .dotnet root folder and the actual install folder that shows running on a Mac.
holds only the .NET assemblies that execute on any platform.
It all works on all .NET Core supported platforms from the
The .dotnet/.store path holds the actual unpacked NuGet single .NET Core Tool package, as long as your code doesn’t
package content for each tool installed. When you run the do anything platform-specific.
launcher (magicwindball.exe on Windows), it loads the .NET
Core runtime and then calls the static void Main() entry point
in the entry assembly of the package. The .exe you see on the
left in Figure 6 is only a stub launcher. If you hook up an IL .NET Core Tools don’t need
decompiler to the EXE as I’ve done in Figure 6 with Reflector, platform-specific builds:
you’ll find that the exe is a native binary, not a .NET assembly.
They run on any supported
Running on Another Platform: Linux with WSL and Mac .NET Core platform from a single
.NET Core Tools are platform agnostic and, assuming your ap-
plication doesn’t use any platform-specific features, they can
code base and NuGet package.
run on Windows, Mac, or Linux from a single distribution.
So, let’s run this .NET Core Tool on Linux using Windows Listing and Managing Installed Tools
Subsystem for Linux (WSL) using the same steps as before. You can check what tools you have installed by using the
Use dotnet tool install and then execute the command. dotnet tool list -g command, as shown in Figure 9.
Figure 6: An installed .NET Core Tool uses a proxy executable to launch the .NET Core Tool.
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 47
it’s better to use the same name for the package ID and
command and to use the most descriptive name possible.
Example Components
To bring home the utility of .NET Core Tools, I’d like to de-
scribe a few of the .NET Core Tools I’ve created and discuss
the hows and whys of creating them. I’ve been huge fan of
these tools because it’s so frictionless to publish a tool for
easy reuse. If it weren’t for the ease of sharing via NuGet,
I probably wouldn’t have bothered sharing these tools
at all.
Simple Tools
Figure 8: .NET Core Tools are cross-platform, here running under Mac in WSL. The first couple of examples are your typical utility tools
that, under normal circumstances, I would have distributed
as a downloadable installer or just a standalone binary. If
a tool is popular enough, I still go that route in addition
to the .NET Core Tool, but I tend to use the .NET Core Tool
rather than a standalone installed application.
48 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
This tool lets me export my Visual Studio snippets into VS To run the converter, you can specify a source snippet or
Code and Rider. It also provides me use a “master” snippet folder and an output path:
repository in Visual Studio that allows me to update snip-
pets there and then easily update the snippets in the other snippetconverter `
environments with the .NET Core Tool. "~\Visual C#\My Code Snippets" `
-o "~\ww-csharp.code-snippets" `
To use this tool: -m vs-vscode -r -d
dotnet Tool install -g snippetconverter To make the snippet location easier to use, the tool lets you
use ~ for the default snippet folders for each IDE. For Vi-
For options, just run it and it shows the options shown in sual Studio, this points to the <Documents>\Visual Studio
Figure 10, which illustrates the functionality best. 2019 Code Snippets folder, for example.
Figure 10: A Snippet Converter tool to convert Visual Studio Snippets to VS Code and Rider.
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 49
Figure 11: Migrated code snippets from the Snippet Converter in VS Code.
.NET Core Tools and Figure 11 shows the source snippet folder and output gen- htmlpackager https://west-wind.com `
Windows Apps erated by the Visual Studio code export: -v -o /temp/captured/MarkdownMonster.html
It’s possible to publish HtmlPackager This creates a single very large but fully self-contained HTML
.NET Core Windows Forms HtmlPackager (https://tinyurl.com/HtmlPackager) is a tool file as shown in Figure 12.
and WPF applications as to package an HTML URL into a fully self-contained “pack-
.NET Core Tools with the
age” or folder, bringing all the content offline so it can be There are other options for creating:
.NET Core 3.x SDKs. However,
viewed completely offline. It’s similar to Save as… in a Web
they’re limited to Windows as
they are obviously Windows-
browser, but you can automate the process. This is useful for • A folder of loose HTML and resource files (-x)
specific technologies. attaching to emails or for archival purposes. • A zip file of the folder of loose HTML and resources (-z)
Additionally, in .NET 5.0, This tool came about because I needed this functionality at Servers
the Windows .NET Core the time for my Markdown Monster (https://markdonwmon- A .NET Core Tool is just a .NET Core application, so you can
runtimes won’t be automatically ster.west-wind.com) editor. I looked around for a command take advantage of just about any .NET Core feature, includ-
installed as part of an SDK line tool but came up with nothing that worked that had a ing the ability to create self-contained Web server applica-
install as they are today in small footprint and no dependencies. As a result, I ended tions and services that you can run locally.
the .NET Core 3.x SDKs, up building a .NET library that I used in Markdown Monster
so there’s no guarantee of initially, but then also built into a .NET Core Tool so it can be LiveReloadServer: A Generic Static File Web Server
the required runtimes being used from the command line and automated. I frequently run local static websites on my development
available in the future. computer for quickly running a SPA application, working
If that’s the case the utility It’s a general-purpose tool and .NET Core Tooling provides a on static website content or one of my many standalone
of a .NET Core Tool for very easy way to publish and share it. JavaScript library projects.
these technologies is
somewhat diminished.
The dotnet-htmlpackager tool can be installed with: I could spin up a full development environment like Visual
Studio and IIS Express, or use something like WebPack to
dotnet tool install -g dotnet-htmlpackager provide infrastructure for hosting and running, but that but
that feels like overkill for many of the simple run and edit
Once installed, you can run it using the help command to scenarios I have. As an alternative, using the LiveReload-
see the command line options. To capture a URL, it uses a Server (https://tinyurl.com/LiveReloadServer), I can quick-
command like this: ly run a local development server and just run a local folder
50 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
as a website. It’s a small, self-contained .NET Core-based To use Live Reload Server:
static Web Server that can serve local static file content out
of an arbitrary folder that you specify. This server can have: dotnet tool install -g LiveReloadServer
• Local static Web content To run it, you simply point it at a --WebRoot folder on your
• Loose Razor pages (optional) local computer and that folder then becomes the content
• Markdown pages (optional) source for the website. Figure 13 shows the LiveReload
server running with requests firing through it.
In addition, it also provides what, for me, is the most useful
feature: The Live Reload functionality is enabled by default so you
can edit static text files and immediately see the changes
• Live reload of changed content (optional) reflected in active browser pages. If you have Razor Pages
and/or Markdown Page processing enabled, you can edit
The live reload functionality is built-in, enabled by default, Razor and Markdown pages and see those pages refreshed
and automatically refreshes any active HTML pages loaded immediately as well.
through the server when an HTML page or any other related
resource like CSS or JavaScript are changed. This makes it a Because LiveReloadServer is a .NET Core Tool, it also works
great, generic tool to use on older non-build process web- great on Mac and Linux even though I originally built it for
sites or tools you might need to run locally to add function- my local Windows set up. After making some very minor ad-
ality and make changes. justments for pathing for Mac and Linux support, the server
now also works on those platforms.
As a .NET Core Tool, it’s easy to install the server and it’s
very quick to run and start up. By default, the server runs as a local computer Web server,
but it can also expose an external port, so it can also be
A standalone local Web server isn’t a new idea, as there have used to host externally accessible sites. This is great for
been static Node.js-based servers like http-server (https:// giving network access to other users on your internal net-
github.com/http-party/http-server) or browser-sync work, or for applications that need to expose Web server
(https://www.browsersync.io/) forever, but these tools re- functionality. The server binaries can also be hosted as full
quire Node,js and the standalone live reload tools like Brows- Web applications in IIS or other external front end servers
erSync I’ve used don’t work very reliably. LiveReloadServer like NGINX, because it’s essentially an ASP.NET Core-hosted
is an alternative and it addresses all these scenarios nicely. application.
Figure 12: Running HTML Packager against a URL produces a single self-contained HTML file.
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 51
lot of existing applications that use large FoxPro code bases,
LiveReloadServer is a simple, haven’t been updated, and just keep ticking along. These
tools have been kept current and continue to allow these an-
generic local Web server cient applications to keep working without major disruption
you can point at a local folder or requiring complete re-writes on other platforms for which
there is often no budget, technical skill, or incentive.
to host a website.
Web Connection has, for many years, used .NET technologies
to provide the interface between a Web Server (IIS only in the
A Legacy Web and Application Server past) and FoxPro and the tech using .NET and COM (ugh) is
The final example is for a legacy application server running as a surprisingly stable and reliable. So, when .NET Core came out
.NET Core Tool. It’s for an ancient integration tool that has recent- a few years ago, it offered several new opportunities to ex-
ly been updated to .NET Core as an option. I maintain a FoxPro tend the Web Server interface tooling Web Connection imple-
legacy product called West Wind Web Connection that still has ments by:
many users—for nearly 25 years now. This is as legacy as it comes,
and you may laugh at technology this old, but it’s still in use. • Providing a fully self-contained development server
• Providing a nearly zero configuration environment
Because the tools I created so many years ago extended Fox- • Its ability to run the server component on non-Win-
Pro functionality to build Web applications, there are still a dows computers
Figure 13: LiveReloadServer generically serving Web content out of a local folder.
52 Using .NET Core Tools to Create Reusable and Shareable Tools and Apps codemag.com
Figure 14: WebConnectionWebServer running a FoxPro server application through .NET Core.
• Its ability to run a local computer or network server The internal server implementation is very similar to the SPONSORED SIDEBAR:
without requiring IIS Live Reload server but extended to handle the Web Con-
• Its ability to run truly local Web applications like desk- nection server protocols so it can handle Web Connection- Get .NET Core Help
top applications specific script handling and request routing that lets FoxPro for Free
server code execute in response to Web requests. The .NET
Long story short, a .NET Core Tool turned out to be great Core implementation was moved from a .NET HTTP Handler Looking to create a
delivery mechanism for someone who needs to run an old to .NET Core Middleware, and it was surprisingly easy with new .NET Core project?
application that was built with Web Connection, but doesn’t 95% code reuse from the existing handler. Get off on the right foot
have access or can’t install IIS on a computer and most of with a FREE hour-long
all, who doesn’t want to set up and configure IIS. Legacy technology is always an eye roller, and I doubt that CODE Consulting session.
any of you will use this technology, but it makes for an in- No strings. No commitment.
Just CODE. Our consultants
This sounds strange, but it’s a very common scenario: A teresting use case of the .NET Core Tool functionality in a
have been working
user calls and says they have a Web Connection application very unconventional scenario.
with the .NET Core and
that was developed 15 years ago, the developer left, and
ASP.NET Core teams since
they need to run the application and perhaps make a few
changes. Setting up an environment in the past wasn’t the Summary the early pre-release builds.
For more information,
easiest thing in the world. With this new component, I can .NET Core Tools provide a great way to share executable code visit www.codemag.com/
whittle that down to: from .NET Core in an easy and platform-independent way. If consulting or email us
you’ve built a NuGet package and published it before, you at [email protected].
• Install the .NET Core SDK. already know how to build and share a .NET Core Tool. .NET
• Install dotnet tool install -g WebConnection. Core Tools are easy to consume, which gives access to a va-
• Point at a Web Connection folder and go. riety of existing tools and, because they’re so easy to share,
promote a community of tools to be created.
A .NET Core Tool here offers a smooth solution to distribute
a server that can then be used to serve an ancient legacy Hopefully, this article has given you some ideas of tools that
application without complex configuration or special instal- you might want to use, or better yet, create and share your
lations required. On the local computer, it’s literally: point own with the community or even just within your organization.
at a Web Connection application folder and go—no further
configuration is required. The same server implementation Rick Strahl
can also be deployed in a live environment with IIS.
codemag.com Using .NET Core Tools to Create Reusable and Shareable Tools and Apps 53
Dr. Neil Roodyn and
Talk to an RD Markus Egger
In this “Talk to an RD” column, Markus Egger and Dr. Neil Roodyn continue their
The Microsoft Regional virtual conversation about the impacts of the COVID-19 crisis. Both are involved with
Director Program managing teams that are now working remotely more than before. Both are involved
The Regional Director Program, or RDs for short,
with customers facing the same issues. This discussion focuses on security issues.
is a program that allows Microsoft to identify
influential individuals in an effort to give the Markus: Do you use Surface Hubs in your with are enterprise-scale organizations. They have
community-at-large access to these individuals, organization? their own Office365, so we’re working with those
and also to provide a point of communication on the inside of their firewall, logged in as an AD
and feedback into Microsoft. Regional Directors Dr. Neil: I’ve been using Surface Hubs, but I sus- under their domain.
do NOT work for Microsoft (and they aren’t pect they’re all switched off right now since no-
paid for being part of the RD program), but body is in the office. But I’m very, very fortunate. Markus: Overall security is pretty good with all
they have a formal relationship with Microsoft I have a Surface Studio on my desk, which is a that stuff, right? I mean, looking at Teams and
that provides them with great insights and
beautiful device. A lot of the teams that I work the security that it has compared to some com-
connections within Microsoft.
with have Surface tablets, Surface Pro, or Surface petitor products that have made big headlines
The Microsoft Regional Director website Books. Or a Lenovo tablet that has a pen or an lately with various security problems. It’s always
(https://rd.microsoft.com) defines the RD iPad with a pen. Microsoft Whiteboard runs on any nice to know that in Teams, security works well.
program in the following words: Windows device and on iPad. If you have a pen, Also, most people already have a license for it be-
you get the extra bit of nice functionality where cause it’s part of Office.
“The Regional Director Program provides Microsoft you can engage. I think the other nice thing
leaders with the customer insights and real- about Whiteboard is that, as different people are Dr. Neil: Right. Microsoft made a big move to
world voices it needs to continue empowering scribbling on the same whiteboard at the same make it free for everyone during this period. So
developers and IT professionals with the world’s time, you see their little icons popping up all over that’s made it useful too, in that if I have a team
most innovative and impactful tools, services, the screen so you can track who’s doing what. that’s not necessarily hooked into the Microsoft
and solutions. Established in 1993, the program ecosystem, I can add them as guests into my do-
consists of 160 of the world’s top technology You can see a bigger picture emerge as multiple main and bring them into conversations.
visionaries chosen specifically for their proven people are scribbling down. You can divide the
cross-platform expertise, community leadership,
page into columns and people can enter stuff in The security aspect, certainly within a domain
and commitment to business results. You will
their own columns, or however you want to do it. within an organization, is incredibly important.
typically find Regional Directors keynoting at
top industry events, leading community groups
You can create notes and move them around on Because there’s a lot of these conversations you
and local initiatives, running technology-focused the page. I found that to be a very useful free- don’t want getting outside of the firewall, right?
companies, or consulting on and implementing form tool in the same way I’ve always liked hav- In the situation we’re in due to COVID-19, we
the latest breakthrough within a multinational ing a whiteboard in a working space when I’m in need to be able to have senior leadership con-
corporation.” the same room as someone. It encourages that versations that you normally would have behind
wider conversation. I think sharing screens fluidly closed doors in a boardroom. You need to do
Regional Directors are expected to have deep and being able to share screens among different them virtually. You need to be sure that they’re
technical understanding of many of the Microsoft people in the conversation is also very powerful. secure. You want to have an environment that
technologies. Not just that, but RDs are expected People want to share, whether it’s a new UI they’re you’re 100% comfortable in.
to have an understanding of, and experience designing or they want to have a conversation
with, competing technologies. RDs are also around some plan they’ve put together. Just being And there are other aspects too, like knowing that
expected to go beyond technical expertise and able to do that in Teams has been powerful. something is recorded. You can see a little dot on
have considerable business expertise. Many RDs your screen right now because I’m recording this
present at corporate events, advise governments Bringing in guests is also very powerful. Knowing call. It’s also important knowing that something
and NGOs, and many similar scenarios. that you can lock MS Teams down to people within has been captured or isn’t being captured. It’s
Feel free to contact any of the Regional Directors your organization, but you can have teams where just extra transparency and extra information.
to get access to an RD’s expertise and a well- you can bring in guests in a controlled fashion is
informed opinion that isn’t shaped or influenced another aspect of it. There are lots of pieces of Markus: I know you’re also very interested in ap-
by having to go along with Microsoft’s marketing the puzzle that connect together to make a very proaching software development with security in
speak. You can contact RDs to get advice and useful toolkit that MS Teams has presented. mind and as a driving factor.
opinions on your projects regarding technical
needs. You can contact them to help analyze Markus: I believe you can use the Whiteboard Dr. Neil: It’s what I’ve started calling “Security
how technology will influence your business. product whether you use Teams or not, is that Driven Development,” copycatting the Test-Driven
You can invite RDs to speak to your project correct? Development that I started pushing 20 years ago
stakeholders, board of directors, or corporate when I was doing all the XP [eXtreme Program-
event. And you can contact your RD for many Dr. Neil: Yes. The Whiteboard product isn’t attached ming] drive, trying to get people into XP and Agile,
more scenarios. to Teams. It’s a separate product. It’s attached to and thinking about how to put quality first. One of
Active Directory. Most of the organizations I work the things that surprises me a little bit in the last
In this feature, we eavesdrop on a conversation between Dr. Neil Roodyn and Markus Egger, both seasoned Regional Directors.
Talk to Dr. Neil about: Talk to Markus about:
Software development, cloud computing, machine learning and AI, ASP.NET, HTML apps
More Personal Computing, cognitive services, (including Angular, Vue.js, etc.), the cloud,
bots, conversation as a platform, true social Azure, Microservices, Windows applications,
computing, robotics, quantum computing, software strategy, and much more.
the economic singularity, and the future. You can contact him at [email protected]
Dr. Neil Roodyn has long had a passion for software development, going Markus Egger is not just an RD, but as the founder and publisher of CODE
back to the 70s when he taught himself BASIC and 6502 Assembler. In the Magazine, he’s also directly associated with this publication. In his main
90s, Neil worked on a number of different real-time systems that led to a job, he is the President and Chief Software Architect of EPS Software Corp.
thesis entitled “Software Architectures for Distributed Real-Time Systems.” (a company better known for its CODE brands such as CODE Consulting,
Neil was awarded a PhD for this thesis from University College London and CODE Training, CODE Staffing, and CODE Magazine). He is also the founder
the brand of Dr. Neil was born. Since 1995, Dr. Neil has been involved in the of other business ventures, such as Tower 48, Wikinome, and others. In his
formation of many software companies, his roles varying from mentoring own words, he spends his time “like most software developers, writing
through to directorship. Dr. Neil keeps a very active involvement in the production code” both for consulting and custom app-dev customers,
software being produced and delivered today, and provides feedback and also for his own companies. He has worked for some of the largest
to both large and small companies on how to increase the value of their companies, including many Fortune 500 companies, such as Microsoft.
software business. Markus often takes on the role as a “CTO for hire.”
through to property management. It’s every- you’re going to send it somewhere else, you’re kind of centralized Identity. Right now, you think about
where. I think if your goal is to build a product out of the realm of them worrying about it. If you’re identity for everything we do. Let’s say you log
that is a global-scale success, if you’re trying to using their messages, the cloud messaging protocol onto Teams; you log on with your username pass-
build a product that’s gonna make you the next that they’ve provided, maybe you’re secured again by word, and maybe you use multifactor authentica-
Apple, Microsoft, Google, Facebook, whatever, what they’re providing. But I think the other thing tion or two factor authentication and get a thing
you have to think about these things. And it’s is to make sure you understand what they’re provid- that comes up on your phone and you say, “yes,”
true even if you’re building an internal product. ing. If you’re using some messaging system hosted and you’re in and that’s great. But who owns that
on a server somewhere hosted by Amazon or Micro- identity? Well, now it’s a Microsoft identity, or it’s
I guess the other thing that’s really brought a lot soft, understand what they’re providing as part of an Active Directory identity, or you log into Gmail
of this to the fore, is horrific legislative activities, that. Even just the fact that you’ve gone and read and and it’s now a Google-owned identity, or you log
like GDPR. Suddenly everyone’s going “The what? understood, means you’re now getting a bit more of into your Amazon admin portal and you’re now
What do we have to do? What do you mean we can’t your head around the concept of what security means. on an Amazon identity, or you log into your Ado-
sell our product in Europe anymore?!?” In many be tools and you’re now on an Adobe identity.
ways, for as much as I hate all the bureaucracy, When they say something that you don’t under-
I think it’s done everyone a big favor in making stand, go and look it up! Hopefully you then under- It’s like, “wait a minute!” How many identities did
them think about what personal information is. stand a bit more about that aspect of the security. I just roll off? Like five, six? And you have all of
What is this data that I’m transferring among 50 I always recommend to everyone that they investi- those, right? I’m sure you do. I’m sure most people
different servers? What does it mean? How am I gate what’s currently provided, even if they’re using have this huge number of identities. Oh, and you
transferring it? Is it accessible to other people? I a standard cloud platform provider. But the other also have a government identity. When you log
think there are a number of factors that have come thing I often say is “don’t trust it.” You want to onto your driving license or to pay your taxes,
into play. The whole GDPR conversation is what’s make sure that it’s secure as far as you’re concerned that’s a different identity. So you just start think-
also driven a lot of these security courses online. or not only secure as far as they’re concerned. And ing “wait a minute, there’s something really wrong
if you want to be the one who’s comfortable with with this picture!” Well, there are multiple things
Markus: How much does moving onto one of those security, maybe you need to add something to that. wrong with this picture [laughs], but the first one
clouds help you with that? Some of the cloud stuff Maybe you need to add a level of encryption or a is that most of them are still relying on a username
forces you into that, doesn’t it? You put up a SQL level of validation. If the only server that’s allowed and password. And 20 years of doing this makes
Azure database and you don’t have quite the free- to send you this kind of information is this or that me feel like this really isn’t right anymore. The
dom to mess up security as you did before. But it’s server, sign it or have a certificate that’s on that other thing is that you’re now giving ownership of
not automatic by any stretch of imagination. server. Then you know it came from the right server the identity of who you are, in different aspects of
and it can’t come from somewhere else. it, to different people, not yourself. You no longer
Dr. Neil: No. And you can break it. [laughs] There own your own identity in the Adobe cloud. You no
are some defaults that all the clouds, whether it’s Markus: I’d imagine you’re still an advocate of longer own your own identity in the Amazon cloud.
Amazon or Microsoft or whoever, give you that not home growing your added solution. You go
are definitely more secure than you would be than with certain standards and encryption mecha-
if you had just gone and installed SQL Server on nisms and standard signing and so on.
a box and connected it to an Internet connec- The compliant way of thinking
tion and started serving up data to your website. Dr. Neil: Absolutely! I don’t want to invent a new about it is blockchain or
There are some defaults that they’ll set up and security protocol. Absolutely not. At the same
there are also some flags that they all give you. time, I don’t think a lot of what comes out of the ledger-based identities.
They give you a little flag saying “Warning. We box is necessarily the best thing. Like, I think a
don’t believe this is secure. You should not use lot of the certificate signing is still 2048 [bit en-
this technique. Using this other technique is our cryption], and really, we probably need to go up Could we change it? Can we turn the whole thing
recommendation.” Not that they actually prevent to 4096 now. You may just want to flip that switch on its head and create a world where you own your
you from doing it wrong. You can go and con- so that you’re using a slightly harder-to-crack set identity and you decide which parts of it you want
figure it how you want and it could be insecure. of tokens. But yeah, I do think that you should to give to different people? You then say, “oh, well,
But the flag is there. And every time you log into first understand it and then use the tools to make for my health records, obviously, I want this part
their portal, you’ll get this alert: “Your SQL server sure you’re making the security harder to crack of my identity, like my date of birth, my address,
is not considered to be secure the way we would and harder for someone to access the data. my next of kin.” Whatever. Those kinds of things.
like it, or the way we would recommend it here.”` That’s part of what you share with your health iden-
Markus: How do you deal with sign-on and IDs tity, but you still log on as the same person when
Markus: Or they might even send you an email. and accounts and all that? you go to Adobe. They don’t need to know anything
about any of that stuff, right? Maybe they need to
Dr. Neil: Yeah. “Click this link to see our recommen- Dr. Neil: [laughs] That’s a super interesting con- know your billing address, but they don’t need to
dations.” There is definitely a base level of value you versation because identity is core to everything know your next of kin or your date of birth.
get from that. But then you get to code you’ve writ- we’re doing. One of the things I spent a bunch of
ten and you’ve pulled that data out of the database, time on last year is looking at different identity You might share a different set of components,
and now you’re going to manipulate it somehow, and solutions. Also digging into this concept of De- but it’s the same identity. That’s this concept of
trying to create a decentralized identity solution. Dr. Neil: Yes. And you could do all of this with payment because they’re a business of some sort.
The buzzword-compliant way of talking about it certificates, as well. Let’s say that I have an cer- They’re looking for ways to gain revenue out of this.
is blockchain or ledger-based identities. That’s a tificate issued to me and Markus says “oh, I trust
technique that you could use to create this decen- what Neil says about a member of staff who used Markus: Who would be the clearing house for
tralized identity, but it definitely seems like an in- to work with Neil” and I’ve signed something and that? Or who provides the API so companies like
teresting way forward and a way out of this multi- validated that the person was a good developer Adobe could integrate into that? If you’re talk-
identity problem and this lack of consolidation to and worked with me and I really enjoyed it and ing about entities like Microsoft or Google, now
who you really are. The great thing is that if you I’ve signed it. There are a lot of these kinds of we’re almost back to a blockchain-based version
were to do this, you could start getting crossover. things that start to become super interesting. of Microsoft Passport.
Say, for example, I want to buy a domain and get a We’d have to get to a point where we could enable
certificate on Azure. Well, how do they know that people to really carry identities in a digital form. Dr. Neil: I think there are two aspects to it. You
it’s really me? At that point, I could share my gov- Right now, that probably means on their phones. just brought up two completely different terms.
ernment identity with them with the same identity You’d carry your identity with you wherever you One was “clearing house” and then “APIs.” I think
that I’m already logged in with and say, “here’s my go and be able to share different aspects of it on the whole point of this is that there’s no clear-
driving license and here’s my passport number and different systems with different people. ing house anymore. Everybody acts as their own
you’re allowed to use it for the next two days in clearing house to a certain degree. You validate
order to issue me with my own domain and my own Markus: Do you envision that will be a completely what you want to have shared from your ledger
certificate for that domain.” And then it disap- new blockchain, or could it reuse something like with other people. You are the person who owns
pears from their data. I’m giving permission to use an Ethereum blockchain? your identity. The API is a different aspect. I’m
this for a period of time and then it gets revoked. sure that over time, this would evolve and there
Dr. Neil: There are lots of different projects afoot will be Microsoft APIs and Google APIs and Ama-
These kinds of concepts are technically very feasible right now. And if anyone’s interested, they can zon APIs for ledger-based identity or certificate-
now. I’m keen to try to work out how I can start help- go and look them up, but there is one based on based identity or however it ends up being
ing organizations think about using a more decen- Ethereum. There’s one based on what you might mushed together. But I think the concept of a
tralized identity within their environment. Because call the “Bitcoin blockchain.” Microsoft has a re- clearing house is what disappears as part of this.
I think that this would enable a much richer digital search project called “Ion” that’s kicked off.
conversation to start happening between systems.
I think what needs to happen, to be of real value, is
Markus: So how do we all imagine this? We were it needs to be disconnected from coin. The problem I’m not convinced that we’re
talking about things like blockchain, but I’m as- with the ones that are connected to coin, in my taking the right route in trying
suming we’re not just talking about blockchain- view, is that then it becomes a pay-for-use scenar-
style technology that sits on a server, but we io. Obviously, they’re motivated by coin-spending. to lock everything down.
would have a very large distributed set up. Al- In order to validate someone to sign something, or
most like Bitcoin using blockchain? to do something of that kind of activity, you pay a
price. I’m not sure that’s correct. I don’t necessar-
Dr. Neil: Yeah. It has to be a set of distributed ily believe you can scale that. If you were going to I think there’s a whole other aspect of this identi-
ledgers that capture the different aspects of what have hundreds of millions of transactions happen- ty security conversation. It’s probably controver-
we’re all doing. ing every minute on the Internet, does it makes sial, but I’m not convinced that we’re taking the
sense that there’s a coin value attached to every right route in trying to lock everything down. The
Markus: Blockchain would mean it’s trustworthy. single time someone logs onto a website to do on- concept of privacy in the modern world is quite a
It’s not changed and so on. It’s not fake. But how line shopping? I think that the future of it needs to modern concept. If you think about us as ancient
do you give it authority in the first place? be disconnected from any coin-based blockchain human beings living in small tribes, there wasn’t
and needs to be independent. There are a few al- really a concept of privacy. I’d know exactly who
Dr. Neil: You’d have authorities in the ledger. The ready starting to pop up that are doing this. you were sleeping with and what you were eat-
Australian government or Hawaiian state govern- ing, because there are only 37 of us in the tribe.
ment are examples of such authorities. Or you Markus: It makes total sense. There’s no reason why [laughs] The concept of privacy in a tribal world
may have the department of driving, or you may a blockchain would need to be coupled to a coin. is kind of bizarre, actually. A lot of cultures never
have hospitals with certain authorities. You can even contemplated privacy as a thing that was
specify what authorities they have in order to be Dr. Neil: The ones that have coin were quite quick a right or even desirable. Everyone knew what
able to carry out certain actions. Or to be able to adopt it because they already have the infra- everyone else was up to and you knew straight
to add something to the chain or to your ledger structure. away that the guy over there is a jerk because
saying, “this is Markus and yes, this is his driving it was obvious because everything was out in
license as issued by Hawaiian driving.” Markus: You could just use an Ethereum-based the open.
blockchain for this.
Markus: There would be other entities that would You still see this a little bit in cultures that have
have the ability to add or allow you to add to it and Dr. Neil: Exactly. You don’t need to have coin at- small communities. I was kind of shocked about this
sign it in some way to know it’s actually for real. tached to it, but of course the platforms require the first time I went to countries like Finland. I went
to Helsinki and was amazed at just how safe it was. I eryone to know about your family life. You take it here in Australia and you’ve been dealing with
used to joke that in a park in Helsinki, you could put your kids to a certain school and you don’t neces- it in the US. We have the same problem here in
your laptop down, go for a walk for 10 minutes, get sarily want everybody to know where your kids are Australia where we have a very high percentage
your coffee, walk back, and your laptop would still at all points in time in order to protect them. Then of indigenous people locked up in prisons com-
be there. I remember once asking a Finnish person it takes on a little bit of a different dimension. pared to the overall percentage of the popula-
about it and she said, “yeah, absolutely.” Because if tion. There’s clearly something broken with that.
so-and-so steals your laptop, everyone in the whole Dr. Neil: It does. Except if you know where all the I think that’s partly because of the lack of trans-
town knows it was him by tomorrow. stalkers are all the time, then maybe that’s less of parency in the whole system. You can look at this
a problem. [laughs] almost throughout the entire world. In some
Anonymity removes accountability and the online places it’s a little less so and somewhere it’s a
world has pushed that to the extreme. What I’m saying is that I think if you really want little more so, but we’re certainly seeing some-
to solve this, you either go all the way to abso- thing that’s a systemic problem worldwide and
Markus: Anonymity removes accountability and lute maximum security. Everything is locked down hopefully we’re seeing a change. Something will
the online world has pushed that to the extreme. and nobody really knows who anybody is. Or you have to change there.
go all the way to complete transparency, where
Dr. Neil: Yeah. The online world has created this there is nothing hidden at all. Then if I want to Markus: That’s actually a very interesting philo-
extra level of anonymous behavior and anony- know where someone was at some point in time, sophical discussion.
mous activity. And maybe the solution is to get it’s there. It’s the in-between that we have the
rid of all of that and make everything incredibly problems with, where some people are more Dr. Neil: Yes! I am not sure how fitting this is for
transparent. anonymous than others. And some people’s ac- an RD column, but it’s super interesting. The soci-
tivity is more hidden than other people’s activ- ety that we live in globally is built on the history
Markus: But then doesn’t that go counter to your ity. I think that’s where a lot of these challenges that made it how it is. We have to accept that part
security-driven development? start. Well, how is he allowed to be secret about of history involved some pretty horrible things.
it? I’m not secret about it. Like slavery, like genocide, like the capture of
Dr. Neil: Absolutely! [laughs] That’s why I think countries that didn’t belong to the conquerors.
it’s interesting! Because I think there are two If you are an amateur money launderer, shall we Let’s face it: The British empire was created be-
ends to this scale. You either go to everything say,… cause they had guns and the other people didn’t.
being totally locked down or you go to nothing We have to really understand how we got to this
being locked down. It’s the in-between that we’re I think just the same with money laundering. Like point before we can come to solutions.
stuck in that’s so troublesome. if you’re an amateur money launder, shall we say.
And I know this because I used to work... This goes all the way back to Roman society. It’s
Markus: Then perhaps we should put everyone’s not hugely surprising that a lot of legal systems
behavior into a blockchain. You can look up all Markus: around the world are based, at some level, on Ro-
the bad stuff someone did. You know, Big Brother ...as a money launderer? [laughs] man law. That’s because the Romans worked out le-
to the max! gal mechanisms that justified their ability to build
Dr. Neil: [laughs]. an empire, take over countries, capture people,
Dr. Neil: You’re not the first to suggest this. turn them into slaves, give them mechanisms to
[laughs] Some people would say this is highly re- Markus: Where do we go with this? We may be become free, have earnouts. These are all concepts
strictive. You’re now observing my every behavior. going somewhere that you don’t want the world that are intrinsic to our behavior and our society.
What are you doing wrong that you don’t want to to know. [laughs] So yes, this is not an easy “let’s turn this switch
be observed? And you have to ask: “why do you over to six and we’ll be fixed” type of situation.
need to be anonymous if you’re not taking bad Dr. Neil: [laughs].I used to work in financial sur-
action?” Are you embarrassed by your activities? veillance. I used to look for bad patterns of behav- Markus: This is a pretty heavy conversation for a
You don’t want to let people know that you went ior and movements of money. There are some in- coding magazine.
to that website. Well, why did you go to their web- teresting things that you learn when you do that.
site? Maybe you should think about that a little One of them is that people who know what they’re Dr. Neil: (laughs) It is. It’s something that needs
bit more and not go to that website. Let’s, for doing are never going to get caught. The people to be discussed everywhere. Nothing can change
the sake of the conversation, say it’s a gambling who generally get caught for doing silly things until we see what’s happening, whether it’s in our
website. I know that wasn’t what you were think- with not paying taxes or whatever, are people who code or our society.
ing. [laughs] So maybe you shouldn’t have gone don’t understand what the rules are or don’t un-
to that gambling website. If you’re embarrassed derstand in general. So what I’m really saying is if Markus: True. Thanks for meeting with me. I’ll be see-
about going to that gambling website, you should you’re good at hiding it, you can hide it. ing you online or at a conference sometime.
have thought about that a little bit harder.
That means it’s different rules for different peo- Dr. Neil: It was fun. Thanks!
Markus: That’s true. On the other hand, it could ple. What I’m saying is if you went to complete
also be a completely different matter. Maybe you’re transparency, you break all that down. We’re Markus Egger
a person in the public eye and you don’t want ev- dealing with this right now. We’re dealing with
interchangeably for the basic reason that crypto currencies data. Perhaps that would call for an IBlockReader interface? Per-
are based on blockchain. But not all blockchains are crypto haps that interface has a generic method that accepts a JSON
currencies. It follows that we can discuss and implement string that was generated from the block’s ToString() method?
blockchain independently of crypto currencies and the peer-
to-peer networks within which the blockchains that are cen-
tral to crypto currencies reside. What Is a Blockchain?
Blockchain isn’t a technology or a third-party service for
None of that resolves the basic question: What are blocks which you need to purchase a seat. You may have heard the
and block chains? What does one look like? Assuming there’s phrases “distributed digital ledger” and “smart contracts”
some value with them, does blockchain, as a concept, apply in the context of decentralization and crypto currencies like John V. Petersen
to your applications? If so, which problems can be solved with Bitcoin. Blockchain is the foundation of distributed digital [email protected]
blockchain and how would you implement those solutions in ledgers and smart contracts. Distributed digital ledgers have linkedin.com/in/johnvpetersen
your applications? To answer those questions, you need a been compared to a spreadsheet that’s replicated and synced
Based near Philadelphia,
tangible proof of concept that makes concrete what has previ- via nodes that are connected via a peer-to-peer network. A
Pennsylvania, John is an
ously been largely an abstract concept. In this article, I tackle smart contract is a program that manages the protocol coor-
attorney, information
these questions with a tangible blockchain proof-of-concept. dinating actions that are incident to some legal obligation.
technology developer,
An example of such an obligation is the requirement to pay a consultant, and author.
Although this article endorses blockchain and despite refer- sum of money in return for a product or service. Blockchain
ring to the crypto currency context, it’s not an endorsement is at the core of it all. The specific programs that implement
of crypto currencies. If there’s one thing to take away from blockchain and the network those programs reside on, those
this article, it’s that although blockchain and crypto currencies are things I’m going to put to the side so that I can focus on
are related, they are in fact, quite distinct things. Crypto cur- blockchain itself as a thing you can implement in your ap-
rencies are still in their infancy and have had their fair share plications. To do that, you need to understand what a block-
of problems. Whether crypto currencies succeed or fail, that chain is and what problems it’s well suited to solve.
has no bearing on blockchain’s efficacy. Editorially speaking,
despite the hype, I don’t see crypto currencies as a viable long- As glib as it may sound, it’s nevertheless accurate to say
term thing. That conclusion is based on several factors: that a blockchain is a chain of blocks. That necessarily raises
two questions: What are blocks and how are blocks chained?
• Acquisition difficulty (at least in the USA)
• Association with nefarious activity As Figure 1 illustrates, a block is a data container. A block
• Uncertain recourse when something goes wrong includes at least two things:
• Not immune to theft
• General uncertainty and risk concerns • Data
• Data Hash
With a few strokes of the legislative pen, crypto currencies as a
form of anonymous payment could very well be outlawed. Who The block data is composed of the following items:
are the only people that place a premium on anonymity in fi-
nancial transactions? Terrorists, money launders, drug dealers, • Business data (order, customer, transaction, or any-
and sex traffickers, to name a few. No legitimate activity re- thing else)
quires crypto currency. Despite the issues with crypto currency, • The previous block’s hash. If this is the first block, the
those issues should not and do not detract from the benefits of value is null
blockchain, the primary enabler of crypto currency. • A nonce value (random integer)
The code for the proof-of-concept discussed in this article A block’s validity is determined by calculating the hash and
can be found here: https://github.com/johnvpetersen/Block- then comparing that value to the stored hash. If those values
Chain. Note: because this is an active repository, although are equal, the block is valid. In a blockchain,
conceptually consistent, there are some deviations with the illustrated in Figure 2, a block’s previous hash
implementation details. It’s baked enough to discuss, but this value must equal the preceding block’s hash
project is very much a work in progress. The goal is for you value. The only exception to the rule is the
to take what I’ve started and make it useful for your specific first block, or what is often referred to as the
use cases. “Genesis block.” The first block’s previous hash
value will always be null. Carrying the previ-
A Quick Word on Encryption ous hash forward to the next block is how the
For the purposes of this proof-of-concept and article, data at blocks are chained together.
rest isn’t encrypted, but it could be. Encryption, however, is a
separate concern. If data within a block is encrypted, it’s the Figure 1: A block is a data container that
responsibility of another facility to decrypt and read the block also includes the hash of its data.
A common way to generate nonce values is via a random number • The validity of any one block can be verified. Does the
generator. This implies a process that continually loops through generated hash == the stored hash? We can easily de-
a process that generates a new random number, generates the tect whether a block’s data has been altered since the
hash, and then compares the generated hash value to a required hash was generated.
prefix specification. This process is the proof-of-work concept • The validity of the blockchain can be verified. Does a
that’s also a core concept in the crypto currency context. Proof of block’s data contain the hash for the previous block?
work is the way nodes on a network achieve consensus on wheth-
er a block can be added to the chain. Another phrase you may You often have the need to quickly verify whether a data
have heard of is “block mining.” The more complex the specifica- series is “Valid.” Valid, in this context, means that the data
tion for the hash, the more computing power you need to find the hasn’t been altered since hashes were generated. Altering
first combination of elements that yields a hash that conforms any one block in the chain not only invalidates that block, but
to the specification so that the block can be added to the chain. it also invalidates every subsequent block and, as a result, the
entire chain is invalidated. If, for a given data set, you were
For an internal application, do you need to implement the called upon to prove whether the dataset has changed, how
proof-of-work concept? The answer is no. Nevertheless, I’ve would you go about handling that task? Is it possible? Would
implemented the concept here because if there’s at least you need to ping off another data source? If you implement
some rule for hash complexity and that rule is secret and blockchain, the task is trivial because a blockchain is capable
embedded in your program, it follows that your program— of expressing whether or not data has been altered since
and only your program—can create blocks. In such a case, a hashes were generated and it can do so within its bound-
block’s provenance is certain, which in turn, enhances the aries without the need for external resources. This can have
blockchain’s data trustworthiness. In other words, a rogue profound positive performance ramifications for your applica-
process can’t create or update blocks in a blockchain. tions! Therefore, in the crypto currency context, blockchain
supports the decentralized digital ledger concept.
A related concept to proof-of-work is proof-of-stake. With
proof-of-work (PoW), any miner that expends the necessary
effort (including energy consumption) can verify a new block.
Blockchain Use Case:
Because of the computing resources required, the energy con- Read-Only Sequential Data
sumption mentioned is just that: electrical power. Miners get The world isn’t a nail and blockchain isn’t a hammer! For
rewards for mining blocks. Those rewards fund the sizeable blockchain, a good use case appears to be one that involves
electrical bills that are incurred with block mining! Proof-of- read-only sequential data. Think about bank account trans-
actions. Once a transaction has been logged, it should never
be altered. Once an event occurs and has been recorded,
there’s no going back. In other words, there is no Wayback
Machine that allows you to go back in time to change his-
tory. If a correction needs to be made, you simply append
a new transaction to record the correction. Or put another
way, add another block to the chain.
Data Class
Listing 1 illustrates the data class implementation. Because
the class is generic, it can host your custom class. In ad-
dition to your business data, this class also contains the
nonce value and the previous block’s hash. The following
illustrates how to instantiate and verify the data class:
[Fact]
public void CanInstantiateData() {
var sut = new Data<MyData>(
0,new MyData(10,"Amount is $10.00"));
Assert.Equal(10,sut.Value.Amount);
Assert.Equal("Amount is $10.00",
sut.Value.Message);
Assert.Equal(0,sut.Nonce);
Assert.True(
string. Figure 4: A block chain is a chain of blocks where each block contains data and the data
IsNullOrEmpty(sut.PreviousHash)); hash. The data is an object that contains a nonce, business data, and, if applicable, the
} previous block’s hash.
• Blocks Property: This property is the public version of • Creates a new chain
the internal blocks dictionary. The System Collections • Adds three blocks
Immutable NuGet Package is leveraged so that you • Serializes the chain
can create an immutable version of the internal blocks • Nulls the blocks variable
dictionary. An external entity needs to read the block • Deserializes the chain from JSON
data in the chain. At the same time, the data needs to • Adds a fourth block
be read-only. Although the underlying block objects
and the data it contains is read-only, the outer dic- [Theory]
tionary is mutable. It isn’t a concern because the vari- [InlineData(true)]
able that holds that mutable dictionary (_blockChain) [InlineData(false)]
is private. The internal dictionary needs to be mutable public void
because blocks may be added. When you refer to the ChainCanBeSerializedAndDeSerialized (
Blocks property, a copy of the _blockChain variable is bool proofOfWork
made. That copy is, however, an immutable dictionary. ) {
• AddBlock() Method: The AddBlock() method is re- var blocks =
sponsible for taking the block data, taking the block new Chain<MyData> (proofOfWork ?
data and computing a hash, and checking to see if the new ProofOfWork() : null);
computed hash conforms to the prefix if a required pre- blocks.AddBlock (
fix applies. That’s why the While loop is in place. The new MyData (108, "Amount is 108"));
process continues to leverage the block’s ability to gen- blocks.AddBlock (
erate hashes until one is generated that conforms to new MyData (109, "Amount is 109"));
the prefix. To achieve that capability, the nonce value blocks.AddBlock (
is updated with another random number. If that didn’t new MyData (110, "Amount is 110"));
happen and given that the other data doesn’t change,
namespace BlockChain string computeHash(Data<T> data)
{ {
public class Block<T> { using (var sha256 = SHA256.Create())
{
private string _hash = string.Empty; return Convert.ToBase64String(
private Data<T> _data; sha256
private string _prefix; .ComputeHash(
Encoding.UTF8.GetBytes(
[JsonConstructor] SerializeObject(
public Block (string hash, Data<T> data,string prefix) { data
_hash = hash; )
_data = data; )
_prefix = prefix; )
} );
}
public Block ( }
T data, string previousHash = "", public override string ToString () {
IProofOfWork proofOfWork = null) { return SerializeObject (this);
_prefix = }
proofOfWork == null ? public string Hash => _hash;
string.Empty : proofOfWork.GetPrefix (); public Data<T> Data => _data;
var rnd = new Random (); public bool IsValid () {
while (true) { var retVal = true;
var blockData = new Data<T> (rnd.Next (), data, previousHash); retVal = string.IsNullOrEmpty (_prefix) ? retVal :
var result = computeHash(blockData); this.Hash.Substring (0, _prefix.Length) == _prefix;
if (string.IsNullOrEmpty (_prefix) || return retVal && computeHash (_data) == this.Hash;
result.Substring (0, _prefix.Length) == _prefix) { }
_hash = result; }
_data = blockData; }
namespace BlockChain { public override string ToString()
{
public class Chain<T>
{ var prefix =
_proofOfWork == null ? string.Empty : _proofOfWork.GetPrefix();
private Dictionary<int, Block<T>> _blockChain =
new Dictionary<int, Block<T>>(); return SerializeObject(
private IProofOfWork _proofOfWork = null; new
public ImmutableDictionary<int, Block<T>> Blocks => {
_blockChain.ToImmutableDictionary(); BlockChain = _blockChain,
ProofOfWork = prefix
[JsonConstructor] }
public Chain( );
Dictionary<int, Block<T>> blockChain, }
IProofOfWork proofOfWork)
{ public void AddBlock(T data)
_proofOfWork = proofOfWork; {
_blockChain = blockChain; var previousHash =
} _blockChain.Count == 0 ?
null :
public Chain(IProofOfWork proofOfWork = null) _blockChain[_blockChain.Count - 1].Hash;
{ _blockChain.Add(
_proofOfWork = proofOfWork; _blockChain.Count,
} new Block<T>(
data,
public bool? IsValid() previousHash,
{ _proofOfWork)
if (Blocks == null || Blocks.Count == 0) );
return null; }
if (Blocks.Count(x => !x.Value.IsValid()) > 0) public Block<T> this[int i] => _blockChain[i];
return false; }
for (int i = 1; i < Blocks.Count; i++) }
{
blocks.AddBlock ( Finally, the chain class ties the blocks together. Like a block
new MyData (111, "Amount is 111")); class, the chain class can express its valid state. If any one
block is invalid, the entire chain is also invalid. Being able to
Assert.Equal(4,blocks.Blocks.Count); determine at a glance and without having to ping off another
} resource like a database whether or not a dataset is valid is a
} performance enhancement. Although you can’t prevent data
tampering with 100% success, you can, at the very least, with
blockchain, detect when data has been altered. In my opin-
Conclusion ion, that ability makes blockchain a powerful approach that
Blockchain, independent of the crypto currency context, is a affords your applications benefits that would otherwise be
simple and powerful concept. A prime use case for blockchain more difficult to realize. It’s important to note that hashing
in a business application is one where there are multiple se- as a means to detect data modifications isn’t a new or novel
quentially created records. The blockchain itself can express concept, and neither is blockchain!
whether it’s in a valid state. A valid state is one where the
computed hash equals the newly generated hash for the data. John V. Petersen
Assuming nothing changed with the data, the computed and
What’s Suspense in Vue3? ponent that uses the Composition API in Vue 3 by using the
While researching and learning about Suspense, I read many setup() function.
articles and watched many videos. I had light bulb moments
and moments of confusion. It’s the confusion that com- Async/Promise Operation with Success
pelled me to explain it clearly and with my own examples. In this first scenario, I’m going to execute an async/promise
operation that results in a successful operation. Listing 1
Suspense creates an execution context or a boundary around shows the complete source code for this section.
the content it wraps. It waits for the component(s) wrapped
inside to be ready before displaying it/them. Meanwhile, it You can play with this example on Suspense with Success
displays a fallback content that could be a text message, here: https://codesandbox.io/s/suspense-success-rzwx3. Bilal Haidar
spinning animation, or any other type of content. [email protected]
The fetch() function, part of the Fetch API (https://devel- https://www.bhaidar.dev
@bhaidar
Initially, the Suspense component displays the fallback con- oper.mozilla.org/en-US/docs/Web/API/Fetch_API), com-
tent by default. The wrapped component makes use of the municates with a remote REST API to return COVID-19 data Bilal Haidar is an
async setup() function and awaits an async/promise opera- by country. It returns a Promise. accomplished author,
tion to fetch data from a back-end server. The moment the Microsoft MVP of 10 years,
promise is resolved successfully, the Suspense component The fetchData() function simulates a delay by using both a ASP.NET Insider, and has
displays the component on the screen. Promise and the setTimeout() function. been writing for CODE
Magazine since 2007.
The Composition API in Vue 3 is implemented via the setup() func- The moment the Promise is resolved and the data is avail-
With 15 years of extensive
tion. To learn more about the Composition API, check out my arti- able, the SampleOne component is ready to be rendered.
experience in Web develop-
cle, “Vue 3 Composition API, Do You Really Need It?” (https://labs. At this time, the wrapping Suspense component inside the
ment, Bilal is an expert in
thisdot.co/blog/vue-3-composition-api-do-you-really-need-it). App component displays it and hides the fallback content. providing enterprise Web
Figure 1 shows the app running. solutions.
If, for whatever reason, the async/promise operation fails
or is pending, the Suspense component continues to show This example demonstrates the safe path. The Suspense He works at Consolidated
the fallback content. You’ll see this in the coming sections. component deals with a successful async/promise operation Contractors Company in
with no surprises! Athens, Greece as a full-
Let me illustrate this with a few examples. Let’s assume that stack senior developer.
you have a component that’s wrapped inside a Suspense com- Async/Promise Operation with Unhandled Failure
In this second scenario, I’ll execute an async/promise op- Bilal offers technical
eration that results in an unhandled failure. To simulate a consultancy for a variety
Promise rejection, I’ll use an incorrect host name in the re- of technologies including
quest URL and see how it behaves. Nest JS, Angular, Vue JS,
JavaScript and TypeScript.
async function fetchData() {
return new Promise(async (resolve) => {
const res = await fetch(
`
https://disease.sh/v3/covid-19/countries/
?yesterday=true&strict=true
`
);
setTimeout(async () =>
resolve(await res.json()), 2000
);
});
}
The rest of the code is kept the same. Notice the use of
diseases instead of disease.
This example demonstrates the use of a Suspense compo- Suspense at the App Level
nent wrapping a component with an async/promise fetch You can position the Suspense component inside the App.vue
operation failing without being handled. component so it wraps the entire app and controls its render-
ing process. Figure 4 illustrates Suspense at the App level.
Async/Promise Operation with Handled Failure
The third and last scenario is handling the async/promise The Suspense component wraps the entire app. The app con-
request failure inside the wrapped component. The Sus- tains Views which, in turn, are composed of Components.
The Suspense component wraps a View. This View is com- • Total cases
posed of a set of Components. • Recovered cases
• Active cases
This option definitely gives you more control and allows your
app to behave differently among the different Suspense
components that it uses. This comes at the expense of hav-
ing several Suspense components and is more complicated
to manage and maintain. Figure 6 illustrates this.
return { createApp(App).mount("#app");
data
}; // Utils
},
template: ` async function fetchData() {
<p style="text-align: center; padding-top: 20px;"> return new Promise(async (resolve, reject) => {
This component is rendered without any data fetched! try {
</p> const res = await fetch(
<pre>{{ data }}</pre> `
` https://diseases.sh/v3/covid-19/countries/
}; ?yesterday=true&strict=true
`
const App = { );
components: { setTimeout(async () =>
SampleThree resolve(await res.json()), 2000
}, );
template: ` } catch {
<h1>Vue 3 Suspense</h1> reject("Failed to load data");
<div class="app"> }
<h3>Async/Promise with Success</h3> });
<Suspense> }
<template #default>
Listing 3: Covid by Country Component To start with, let’s build a function to fetch the data from
import { computed, ref } from "./vue.esm-browser"; the backend.
Figure 4: Suspense at the App Level. Figure 5: Suspense at the View Level.
You have two options for handling errors when you’re using
the Suspense component.
return {
covid: computed(() => {
return data.value;
})
};
},
This hook perfectly fits the scenario here. Let’s use it inside
the App component (the component that hosts the Sus-
Figure 7: Preloading and loading of COVID-19 data. pense component).
setup() {
...
const error = ref(null);
onErrorCaptured(
(e: Error) => (error.value = e)
);
return {
error,
...
};
},
The line above fails and throws an exception. The try/catch template: `
block handles the exception and rejects the Promise. <h1>COVID-19 Dashboard</h1>
<div class="app">
Option 1: Handle Errors at the Parent Component <h3>Data by Country</h3>
Before I jump in and implement the solution, let me remind <div class="space-up error" v-if="error">
you of how the setup() function looks inside the CovidBy- {{ error }}
Country component. </div>
<Suspense v-else>
async setup(props: any) { ...
const data = ref(null); </Suspense>
That’s it!
Now let’s see how you can handle errors at the child compo-
nent without touching the parent component.
async setup(props: any) { Figure 9 shows the app running. Vue 3 Docs
...
const error = ref(null); You can play with this example on Handling Errors at the The Vue team provides
Child Component here: https://codesandbox.io/s/suspense- and maintains a detailed
try { handle-errors-child-vue3-civvr. documentation on the
data.value = framework that you may
await fetchData(props.timeout);
always use as a reference:
} catch (err) { Bonus: Custom Suspense https://v3.vuejs.org/guide/
error.value = err; Component with Error Handling introduction.html
} I’ve included this section to clean up the way I handle errors
with the new Suspense component.
return {
... By default, the Suspense function can either display the
error default template or the fallback template. It leaves out
}; handling errors and lets the developer do it their own
}, way.
When you safely handle any errors at the child component In this section, I’ll propose a rather opinionated approach
level, the async setup() function resolves successfully. Hence, on how to extend the Suspense component to offer a third
the Suspense component that hosts this child component dis- template: the error template.
plays the default template—the CovidByCountry component—
and hides the fallback content. You are, more or less, tricking My approach can be summarized in three important points:
the Suspense component into believing all is well. In fact,
when you handle the HTTP request calls properly, things are • Wrap the Suspense component inside a parent com-
fine even though the data cannot be retrieved! ponent.
• Handle the onErrorCaptured() inside the parent com-
Let’s have a look at the template now: ponent.
• Use Vue Slots to render the default, fallback, and error
<div class="space-up error center" v-if="error"> templates.
{{ error }}
</div> To learn more about the Vue Slots, check out my article:
<div v-else class="covid"> Content Distribution in Vue JS (https://labs.thisdot.co/
<div class="covid-line" blog/content-distribution-in-vue-js).
v-for="record in covid"
:key="record.countryInfo._id"> Wrap the Suspense Component
... Let’s wrap the Suspense component inside a new compo-
</div> nent named SuspenseWithErrors.
</div>
export default {
The error message is shown when there’s an error. Other- name: "SuspenseWithErrors",
wise, the template displays the list of all countries with CO- template: `
VID-19 data. <Suspense>
Notice how the SuspenseWithErrors component now with boilerplate logic to show or hide the main
supports three templates: error, default, and fallback. component once its data is loaded and ready for
display on the page.
In addition, note how the Error template accesses Nov/Dec 2020
its Error property, that the SuspenseWithErrors In this case, Vue 3 Suspense eliminates it. The API Volume 21 Issue 6
component binds on it by binding the name of is pretty good, straightforward and easy to use.
the slot to the Props property. The Props object Group Publisher
holds any property bound to this slot. You access Still, I believe this new feature comes with its own Markus Egger
the Error property by using props.error. “side-effects.” The major one is deciding where in Associate Publisher
your app to use the <Suspense /> component. In Rick Strahl
Figure 10 shows the app running. other words, deciding on the level of isolation is Editor-in-Chief
the real challenge. Rod Paddock
You can play with this example on Suspense With Er-
Managing Editor
rors here: https://codesandbox.io/s/suspense-with- In future articles, I look forward to discussing Ellen Whitney
errors-wrapper-bijok. the challenges that arise and sharing solutions
with you as I come across them. Until then, happy Content Editor
Melanie Spiller
coding.
Conclusion Editorial Contributors
Otto Dobretsberger
Let’s be honest here, for every Vue app I’ve devel- Bilal Haidar Jim Duffy
oped, I’ve had to always include a Vue component Jeff Etter
Mike Yeager
definitions that exist separate and distinct from Two additional words that come to mind are Ac- or she acts on behalf can be guided in a correct
the facts. If such definitions exist, from there, we countable and Responsible: direction, there can’t be an adversarial relation-
can apply those definitions to the facts to formu- ship between the leader and the people being
late a conclusion. • Accountable: Required or expected to jus- led. Leaders respond; they don’t react.
tify actions or decision; responsible
The definitions offered herein are not subject to • Responsible: Having an obligation to do So far, nothing speaks to knowledge and skill.
debate as they’re straight out of the dictionary. something, or having control over or care But there’s a fundamental threshold issue to ad-
As for whether the qualities I’m outlining here for someone, as part of one’s job or role dress, it’s whether a person is capable of being a
are hallmarks of leadership, that might require leader. This is over and above the technical quali-
subjective evaluation. Then again, if we look at The implication of being accountable and respon- ties required for the task at hand.
recognized leaders in history, what qualities do sible is that there is some duty.
they tend to possess? If someone doesn’t possess Competence: Having the Necessary Ability,
the qualities discussed herein, are they more or Duty: A Moral or Legal Obligation; Knowledge, or Skill to Do Something
less likely to be truly regarded as leaders? Responsibility Successfully
Because the context is about acting on the behalf Somebody can be physically at the top of some or-
What are the qualities of leadership? of others, going in a chosen direction to achieve ganizational structure by virtue of some other pro-
an objective, a leader must show some regard cess. Do they occupy the position held solely be-
for the future. When acting on behalf of others, cause of merit? Or are politics involved? The person
Defining the Words duty is all about the best interest of others. Lead- may be expert at the tasks accomplished by the
A good place to start is with the word “lead” itself. ers avoid conflict of interest from subordinating team, and yet totally incompetent insofar as being
other interests to their own self-interests, with a leader is concerned. In management, this is the
respect to the future. Peter Principle where people tend to rise to their
level of incompetence. There’s also the notion that
Lead: To be a route or means Prudent: Acting with or Showing Care and past success isn’t a guarantee of future success.
of access to a particular Thought for the Future
Duty and prudence imply that a leader is a fiduciary, Of course, no one person is an expert in all
place or a in a particular which is a relationship that has trust as its corner- things. A leader defers to others who know more
direction. To be in charge stone. When a leader advocates a point of view, we about an issue.
of or in command of. know instinctively whether they believe what they
say. It also implies how decisions get made. Deference: Humble Submission and Respect
Deference is about knowing what one doesn’t
Equitable: Fair and Impartial know and acknowledging that fact so that the per-
The concept of leadership is about one person Fair: Decisions are made based on facts, and al- son who’s responsible for achieving some objective
acting on behalf of one or more other people. ways in the best interest of whomever is to be can fulfill that duty. Often, leading means stepping
Leadership is also about going in some direction served regardless of whether it is in the best in- back to let others take the reins on a particular is-
to achieve some objective. That implies that lead- terest of the person tasked with making the de- sue. A hallmark of recognized great leaders is that
ership is about moving in what could be judged to cision. That, however, is not enough. Impartial: they don’t ever seek to portray the myth that they
be the correct direction so that the correct objec- Such decision must be unbiased and not in favor are the smartest person in the room on all topics.
tive can be achieved. of a specific individual or group of individuals.
This is often referred to as leading from behind
One approach in describing what something is Communication is always key. To act on behalf of and servant leadership. A leader understands
can be to provide an example of what it’s not. others requires sound communication. that their role can often be one of support and
to do the blocking and tackling in order for oth-
Respond: Act or Behave in Reaction to ers to be able to do their jobs. This is where ego
Someone or Something becomes an issue. Ego is about a person’s self-
Mislead: To cause (someone) How do good leaders respond? Like leading vs. esteem or self-importance.
to have a wrong idea misleading, it’s good to flip the problem on its
or impression about ear and review from the opposite perspective. All leaders have egos. They believe they can do
the job and they often believe they are the best
someone or something. React: Responding with hostility. If a leader is to
engender trust such that the people for whom he (Continued on page 73)
codemag.com/magazine
832-717-4445 ext. 8 • [email protected]
HERE ARE
750 BILLION REASONS
WHY DEVS SHOULD
READ THIS AD.
Presenting Fortellis, the open-exchange marketplace
serving the $750-billion auto industry.
On the Fortellis platform, APIs can be securely published, conveniently
administered and consumed at scale by a continually expanding universe
of developers, dealers and manufacturers. You and your APIs and apps will
be connected to an industry with a voracious appetite for them, and we’ll
even handle the integrations and go-to-market strategy.
OUR PLATFORM: