SlideShare a Scribd company logo
© 2018 ServiceNow All Rights Reserved
Making Service Portal Widgets
Work Together
Travis Toulson
Sr. Architect
GlideFast Consulting
© 2016 ServiceNow All Rights Reserved 2Confidential
2
#Know18
© 2018 ServiceNow All Rights Reserved
Widgets are volatile,
self-obsessed, and
don’t play well with
others
Problem
© 2016 ServiceNow All Rights Reserved 3Confidential
3
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
The Design
Powerful widgets simplify
everything else
© 2016 ServiceNow All Rights Reserved 4Confidential
4
#Know18
© 2018 ServiceNow All Rights Reserved
BUT…
© 2016 ServiceNow All Rights Reserved 5Confidential
5
#Know18
© 2018 ServiceNow All Rights Reserved
© 2016 ServiceNow All Rights Reserved 6Confidential
6
#Know18
© 2018 ServiceNow All Rights Reserved
Massive
Widgets
Repetitive
Widgets
VS
© 2016 ServiceNow All Rights Reserved 7Confidential
7
#Know18
© 2018 ServiceNow All Rights Reserved
Embed widgets to
compose complex
behaviors
#1
© 2016 ServiceNow All Rights Reserved 8Confidential
8
#Know18
© 2018 ServiceNow All Rights Reserved
ç
Data Table Widget
- 7 Different Behaviors
- Over 300 lines of client
code
- Over 150 lines of server
code
© 2016 ServiceNow All Rights Reserved 9Confidential
9
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 10Confidential
10
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 11Confidential
11
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 12Confidential
12
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 13Confidential
13
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 14Confidential
14
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 15Confidential
15
#Know18
© 2018 ServiceNow All Rights Reserved
A “child scope” (prototypically)
inherits properties from its
“parent scope”
“
- AngularJS Developer Guide
© 2016 ServiceNow All Rights Reserved 16Confidential
16
#Know18
© 2018 ServiceNow All Rights Reserved
<a style="display: inline;" href>{{page.title}}</a>
Data Table Widget
HTML Template
© 2016 ServiceNow All Rights Reserved 17Confidential
17
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
{{page.title}}
Data Table Widget
doesn’t have a page
object?!?!
© 2016 ServiceNow All Rights Reserved 18Confidential
18
#Know18
© 2018 ServiceNow All Rights Reserved
Child Widgets inherit
functions and data
from their Parent
Widgets
© 2016 ServiceNow All Rights Reserved 19Confidential
19
#Know18
© 2018 ServiceNow All Rights Reserved
Structure application
models with Angular
Services
#2
© 2016 ServiceNow All Rights Reserved 20Confidential
20
#Know18
© 2018 ServiceNow All Rights Reserved
You can use services to organize
and share code across your app
“
- AngularJS Developer Guide
© 2016 ServiceNow All Rights Reserved 21Confidential
21
#Know18
© 2018 ServiceNow All Rights Reserved
1. Create the Angular Provider
2. Add it to the Widget’s Angular
Provider Related List
3. Inject the dependency into the
Client Script
Wire up a Service
© 2016 ServiceNow All Rights Reserved 22Confidential
22
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 23Confidential
23
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 24Confidential
24
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 25Confidential
25
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 26Confidential
26
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 27Confidential
27
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 28Confidential
28
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 29Confidential
29
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 30Confidential
30
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 31Confidential
31
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 32Confidential
32
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 33Confidential
33
#Know18
© 2018 ServiceNow All Rights Reserved
<div ng-repeat=“inc in c.getIncidents()”>
<!-- Incident Template Here -->
</div>
Digest Loop
HTML Template
© 2016 ServiceNow All Rights Reserved 34Confidential
34
#Know18
© 2018 ServiceNow All Rights Reserved
Use Angular Events as
a last resort
#3
© 2016 ServiceNow All Rights Reserved 35Confidential
35
#Know18
© 2018 ServiceNow All Rights Reserved
Insanity Warning: scope depth-
first traversal. Yes, this code is a
bit crazy, but it works and we
have tests to prove it
“
- Line 1417, rootScope.js AngularJS Source Code
© 2016 ServiceNow All Rights Reserved 36Confidential
36
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
Event Propagation
$rootScope
$scope
$broadcast
$emit
$on
© 2016 ServiceNow All Rights Reserved 37Confidential
37
#Know18
© 2018 ServiceNow All Rights Reserved
But given that it’s a
stupid a** decision,
I’ve elected to ignore
it
© 2016 ServiceNow All Rights Reserved 38Confidential
38
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 39Confidential
39
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 40Confidential
40
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 41Confidential
41
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 42Confidential
42
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 43Confidential
43
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 44Confidential
44
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 45Confidential
45
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 46Confidential
46
#Know18
© 2018 ServiceNow All Rights Reserved
Embed
widgets to
compose
complex
behaviors
#1
Structure
application
models with
Angular
Services
#2
Use Angular
Events as a
last resort
#3
© 2016 ServiceNow All Rights Reserved 47Confidential
47
#Know18
© 2018 ServiceNow All Rights Reserved
© 2016 ServiceNow All Rights Reserved 48Confidential
48
#Know18
© 2018 ServiceNow All Rights Reserved
Travis Toulson
Sr. Architect
GlideFast Consulting
travis.toulson@glidefast.com
Thank You

More Related Content

Similar to Making Service Portal Widgets Work Together

Chris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web AppsChris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web Apps
Danielle A Vincent
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Amazon Web Services
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScriptGlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
Jonathan Baker
 
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with FargateDEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
Amazon Web Services
 
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Amazon Web Services
 
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Amazon Web Services
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) Meetup
Ibrahim Abubakari
 
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Amazon Web Services
 
How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2
Hirokazu Nishi
 
The Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for IndonesiaThe Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for Indonesia
Robert Nyman
 
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxData
 
DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJS
DataStax Academy
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
Ignacio Martín
 
Developing Business Blockchain Applications on Hyperledger
Developing Business  Blockchain Applications on Hyperledger Developing Business  Blockchain Applications on Hyperledger
Developing Business Blockchain Applications on Hyperledger
IMC Institute
 
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
Amazon Web Services
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
Zend by Rogue Wave Software
 
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
DevOps.com
 
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC
 
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Zeeshan Rahman
 
Urban Airship & Android Application Integration Document
Urban Airship & Android Application Integration DocumentUrban Airship & Android Application Integration Document
Urban Airship & Android Application Integration Document
mobi fly
 

Similar to Making Service Portal Widgets Work Together (20)

Chris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web AppsChris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web Apps
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScriptGlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
 
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with FargateDEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
 
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
 
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) Meetup
 
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
 
How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2
 
The Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for IndonesiaThe Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for Indonesia
 
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
 
DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJS
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Developing Business Blockchain Applications on Hyperledger
Developing Business  Blockchain Applications on Hyperledger Developing Business  Blockchain Applications on Hyperledger
Developing Business Blockchain Applications on Hyperledger
 
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
 
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
 
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇
 
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...
 
Urban Airship & Android Application Integration Document
Urban Airship & Android Application Integration DocumentUrban Airship & Android Application Integration Document
Urban Airship & Android Application Integration Document
 

Recently uploaded

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 

Recently uploaded (20)

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 

Making Service Portal Widgets Work Together

  • 1. © 2018 ServiceNow All Rights Reserved Making Service Portal Widgets Work Together Travis Toulson Sr. Architect GlideFast Consulting
  • 2. © 2016 ServiceNow All Rights Reserved 2Confidential 2 #Know18 © 2018 ServiceNow All Rights Reserved Widgets are volatile, self-obsessed, and don’t play well with others Problem
  • 3. © 2016 ServiceNow All Rights Reserved 3Confidential 3 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget The Design Powerful widgets simplify everything else
  • 4. © 2016 ServiceNow All Rights Reserved 4Confidential 4 #Know18 © 2018 ServiceNow All Rights Reserved BUT…
  • 5. © 2016 ServiceNow All Rights Reserved 5Confidential 5 #Know18 © 2018 ServiceNow All Rights Reserved
  • 6. © 2016 ServiceNow All Rights Reserved 6Confidential 6 #Know18 © 2018 ServiceNow All Rights Reserved Massive Widgets Repetitive Widgets VS
  • 7. © 2016 ServiceNow All Rights Reserved 7Confidential 7 #Know18 © 2018 ServiceNow All Rights Reserved Embed widgets to compose complex behaviors #1
  • 8. © 2016 ServiceNow All Rights Reserved 8Confidential 8 #Know18 © 2018 ServiceNow All Rights Reserved ç Data Table Widget - 7 Different Behaviors - Over 300 lines of client code - Over 150 lines of server code
  • 9. © 2016 ServiceNow All Rights Reserved 9Confidential 9 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 10. © 2016 ServiceNow All Rights Reserved 10Confidential 10 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 11. © 2016 ServiceNow All Rights Reserved 11Confidential 11 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 12. © 2016 ServiceNow All Rights Reserved 12Confidential 12 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 13. © 2016 ServiceNow All Rights Reserved 13Confidential 13 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 14. © 2016 ServiceNow All Rights Reserved 14Confidential 14 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 15. © 2016 ServiceNow All Rights Reserved 15Confidential 15 #Know18 © 2018 ServiceNow All Rights Reserved A “child scope” (prototypically) inherits properties from its “parent scope” “ - AngularJS Developer Guide
  • 16. © 2016 ServiceNow All Rights Reserved 16Confidential 16 #Know18 © 2018 ServiceNow All Rights Reserved <a style="display: inline;" href>{{page.title}}</a> Data Table Widget HTML Template
  • 17. © 2016 ServiceNow All Rights Reserved 17Confidential 17 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget {{page.title}} Data Table Widget doesn’t have a page object?!?!
  • 18. © 2016 ServiceNow All Rights Reserved 18Confidential 18 #Know18 © 2018 ServiceNow All Rights Reserved Child Widgets inherit functions and data from their Parent Widgets
  • 19. © 2016 ServiceNow All Rights Reserved 19Confidential 19 #Know18 © 2018 ServiceNow All Rights Reserved Structure application models with Angular Services #2
  • 20. © 2016 ServiceNow All Rights Reserved 20Confidential 20 #Know18 © 2018 ServiceNow All Rights Reserved You can use services to organize and share code across your app “ - AngularJS Developer Guide
  • 21. © 2016 ServiceNow All Rights Reserved 21Confidential 21 #Know18 © 2018 ServiceNow All Rights Reserved 1. Create the Angular Provider 2. Add it to the Widget’s Angular Provider Related List 3. Inject the dependency into the Client Script Wire up a Service
  • 22. © 2016 ServiceNow All Rights Reserved 22Confidential 22 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 23. © 2016 ServiceNow All Rights Reserved 23Confidential 23 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 24. © 2016 ServiceNow All Rights Reserved 24Confidential 24 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 25. © 2016 ServiceNow All Rights Reserved 25Confidential 25 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 26. © 2016 ServiceNow All Rights Reserved 26Confidential 26 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 27. © 2016 ServiceNow All Rights Reserved 27Confidential 27 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 28. © 2016 ServiceNow All Rights Reserved 28Confidential 28 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 29. © 2016 ServiceNow All Rights Reserved 29Confidential 29 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 30. © 2016 ServiceNow All Rights Reserved 30Confidential 30 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 31. © 2016 ServiceNow All Rights Reserved 31Confidential 31 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 32. © 2016 ServiceNow All Rights Reserved 32Confidential 32 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 33. © 2016 ServiceNow All Rights Reserved 33Confidential 33 #Know18 © 2018 ServiceNow All Rights Reserved <div ng-repeat=“inc in c.getIncidents()”> <!-- Incident Template Here --> </div> Digest Loop HTML Template
  • 34. © 2016 ServiceNow All Rights Reserved 34Confidential 34 #Know18 © 2018 ServiceNow All Rights Reserved Use Angular Events as a last resort #3
  • 35. © 2016 ServiceNow All Rights Reserved 35Confidential 35 #Know18 © 2018 ServiceNow All Rights Reserved Insanity Warning: scope depth- first traversal. Yes, this code is a bit crazy, but it works and we have tests to prove it “ - Line 1417, rootScope.js AngularJS Source Code
  • 36. © 2016 ServiceNow All Rights Reserved 36Confidential 36 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget Event Propagation $rootScope $scope $broadcast $emit $on
  • 37. © 2016 ServiceNow All Rights Reserved 37Confidential 37 #Know18 © 2018 ServiceNow All Rights Reserved But given that it’s a stupid a** decision, I’ve elected to ignore it
  • 38. © 2016 ServiceNow All Rights Reserved 38Confidential 38 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 39. © 2016 ServiceNow All Rights Reserved 39Confidential 39 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 40. © 2016 ServiceNow All Rights Reserved 40Confidential 40 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 41. © 2016 ServiceNow All Rights Reserved 41Confidential 41 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 42. © 2016 ServiceNow All Rights Reserved 42Confidential 42 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 43. © 2016 ServiceNow All Rights Reserved 43Confidential 43 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 44. © 2016 ServiceNow All Rights Reserved 44Confidential 44 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 45. © 2016 ServiceNow All Rights Reserved 45Confidential 45 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 46. © 2016 ServiceNow All Rights Reserved 46Confidential 46 #Know18 © 2018 ServiceNow All Rights Reserved Embed widgets to compose complex behaviors #1 Structure application models with Angular Services #2 Use Angular Events as a last resort #3
  • 47. © 2016 ServiceNow All Rights Reserved 47Confidential 47 #Know18 © 2018 ServiceNow All Rights Reserved
  • 48. © 2016 ServiceNow All Rights Reserved 48Confidential 48 #Know18 © 2018 ServiceNow All Rights Reserved Travis Toulson Sr. Architect GlideFast Consulting travis.toulson@glidefast.com Thank You