SlideShare a Scribd company logo
1 of 32
Writing
JavaScript
for C#'s
Blazor
#DOTNETFRONTEND
Ed Charbeneau
Author:
Pr. Developer Advocate
Progress Software,
Telerik UI for Blazor
“Blazor: A Beginner's Guide” (free)
Тwitter: @EdCharbeneau
Тwitch: Twitch.tv/EdCharbeneau
Why do we need it?
Blazor is really, really, new!
C# Doesn’t have a full API surface for the Browser’s Web APIs
Why do don’t we need it?
LocalStorage
◦ dotnet add package Blazored.LocalStorage
MediaQueries
◦ dotnet add package BlazorPro.BlazorSize
File Uploads
◦ dotnet add package Telerik.UI.for.Blazor
• Commercial library
.NET 5, 6+
◦ SEO support, <Head>
What’s the JavaScript Interop
A Blazor app can invoke JavaScript functions from .NET methods
and .NET methods from JavaScript functions.
How do we do it?
C# API
DotNetObjectReference<T>
◦ Value (T instance)
◦ Dispose()
IJSRuntime
◦ .InvokeAsync<T>(fname, p)
◦ .InvokeVoidAsync(fname, p)
JAVASCRIPT API
DotNetObjectReference
◦ number | string (guid)
◦ invokeMethodAsync(fname, p)
◦ dispose
Parameters & Values must be JSON serializeable
How do we do it?
CONVENTION
Use namespaces
window.namespace.function
window.myFoo = {
doFoo: function() {}
}
UNLESS
The function already exists on the
window object.
window.alert
Parameters & Values must be JSON serializeable
InvokeVoidAsync
@inject IJSRuntime js
await js.InvokeVoidAsync("myFunction", "Hello");
window.myFunction = (text) => alert(text);
JS C#
Component Lifecycle Awareness
SetParametersAsync()
OnInitializedAsync()
OnParametersSetAsync()
OnAfterRenderAsync(bool
firstRender)
ShouldRender()
Avoid JavaScript interop during
Initialization. Because Blazor can
utilize Server rendering, JavaScript
may not be available.
Use OnAfterRenderAsync for
initializing JavaScript.
Lazy Loaing Modules
Lazy<Task<IJSObjectReference>>
InvokeAsync<IJSObjectReference>
private readonly Lazy<Task<IJSObjectReference>> moduleTask;
public MyService(IJSRuntime jsRuntime)
{
moduleTask = new(() =>
jsRuntime.InvokeAsync<IJSObjectReference>("import",
"./_content/Namespace/module.js").AsTask());
}
public async Task Foo() {
module.InvokeVoidAsync("method", args)
}
let module = await
import('/modules/module.js');
JS C#
Scenarios
One Way
Round-Trip
Round-Trip Callback
Throttle Events
Scenarios: One Way
Invoke JavaScript from C#
Fire and forget
No return value
private readonly IJSRuntime jsRuntime;
private async ValueTask Cancel() =>
await jsRuntime.InvokeVoidAsync($“namespace.functionName“, parameters);
C# JS window.alert
Void
C#
window.namespace = { function: functionName() } JS
Scenarios: Round Trip (C# <-> JS)
Invoke JavaScript from C#
Return value
C# JS invokeMethod
Value
string name = await js.InvokeAsync<string>("prompt", "What is your name?");
Result = $"Your name is: {name}";
C#
Scenarios: Round Trip (JS <-> C#)
[JSInvokable] Attribute
Invoke C# Static Method from JS
JS C# RaiseEvent
Value
[JSInvokable]
[JSInvokable]
public static Task<int[]> ReturnArrayAsync()
Task.FromResult(new int[] { 1, 2, 3 });
returnArrayAsyncJs: function () {
DotNet.invokeMethodAsync(‘namespace', 'ReturnArrayAsync')
.then(data => {
data.push(4);
console.log(data);
});
},
C#
JS
Scenarios: Round-Trip Callback
Invoke JavaScript from .NET
Invoke C# Instance Method from JS
DotNetObjectReference
Dispose, dispose, dispose
C# JS
Function.callbac
k
Value
R
R
Instance.method
Scenarios: Round-Trip Callback
public class GeoLocation
{
public async ValueTask GetCurrentPosition(...) =>
await js.InvokeVoidAsync
("blazorGeolocation.getCurrentPosition",
DotNetObjectReference.Create(this), options);
[JSInvokable]
public void RaiseOnGetPosition(Position p) =>
[JSInvokable]
public void RaiseOnGetPositionError(Error err) =>
window.blazorGeolocation = {
getCurrentPosition: function (geolocationRef, options) {
navigator.geolocation
.getCurrentPosition(onSuccess, onError, options);
},
function onSuccess(result) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPosition’,
blazorGeolocation.toSerializeable(result));
};
function onError(er) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPositionError’,
er.code);
};
};
JS
C#
Scenarios: Round-Trip Callback
public class GeoLocation
{
public async ValueTask GetCurrentPosition(...) =>
await js.InvokeVoidAsync
("blazorGeolocation.getCurrentPosition",
DotNetObjectReference.Create(this), options);
[JSInvokable]
public void RaiseOnGetPosition(Position p) =>
[JSInvokable]
public void RaiseOnGetPositionError(Error err) =>
window.blazorGeolocation = {
getCurrentPosition: function (geolocationRef, options) {
navigator.geolocation
.getCurrentPosition(onSuccess, onError, options);
},
function onSuccess(result) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPosition’,
blazorGeolocation.toSerializeable(result));
};
function onError(er) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPositionError’,
er.code);
};
};
JS
C#
Scenarios: Round-Trip Callback
public class GeoLocation
{
public async ValueTask GetCurrentPosition(...) =>
await js.InvokeVoidAsync
("blazorGeolocation.getCurrentPosition",
DotNetObjectReference.Create(this), options);
[JSInvokable]
public void RaiseOnGetPosition(Position p) =>
[JSInvokable]
public void RaiseOnGetPositionError(Error err) =>
window.blazorGeolocation = {
getCurrentPosition: function (geolocationRef, options) {
navigator.geolocation
.getCurrentPosition(onSuccess, onError, options);
},
function onSuccess(result) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPosition’,
blazorGeolocation.toSerializeable(result));
};
function onError(er) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPositionError’,
er.code);
};
};
JS
C#
Scenarios: Round-Trip Callback
public class GeoLocation
{
public async ValueTask GetCurrentPosition(...) =>
await js.InvokeVoidAsync
("blazorGeolocation.getCurrentPosition",
DotNetObjectReference.Create(this), options);
[JSInvokable]
public void RaiseOnGetPosition(Position p) =>
[JSInvokable]
public void RaiseOnGetPositionError(Error err) =>
window.blazorGeolocation = {
getCurrentPosition: function (geolocationRef, options) {
navigator.geolocation
.getCurrentPosition(onSuccess, onError, options);
},
function onSuccess(result) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPosition’,
blazorGeolocation.toSerializeable(result));
};
function onError(er) {
return geolocationRef
.invokeMethodAsync('RaiseOnGetPositionError’,
er.code);
};
};
JS
C#
Pub-Sub
JS C#
DOM EventA
DOM EventB
Channel
Component (A)
Component (AB)
Component (B)
Component (AB)
Pub-Sub: Init
JS C#
Channel
Component (A)
.addEventListener
DOM EventA
Pub-Sub: De-dupe
JS C#
Channel
Component (A)
.addEventListener
DOM EventA
DOM EventB Component (AB)
DOM EventA
Pub-Sub: Dispose
JS C#
DOM EventA
DOM EventB
Channel
Component (A)
Component (AB)
Component (B)
Component (AB)
.removeEventListener
.Dispose
Pub-Sub: Developer Experience
JS C#
DOM EventA
DOM EventB
Channel
Component (A)
Component
(AB)
Component (B)
Component
(AB)
<MediaQueryList>
<MediaQuery>
<MediaQuery>
<MediaQuery>
<MediaQuery>
mediaQueryLists: MediaQueryListItem[]
MediaQueryListItem {
id: number | string;
dotnetCallback: (ev: MediaQueryListEvent)
mediaQueries: MediaQueryList[];
}
Scenario: Throttle Events (Blazor
Server)
A B C D E F G
A D G
throttleTime(n_ms)
Scenario: Throttle Events (Blazor
Server)
this.reportRate = 300;
this.throttleResizeHandler = () => {
clearTimeout(this.throttleResizeHandlerId);
this.throttleResizeHandlerId = window.setTimeout(this.resizeHandler, this.options.reportRate);
};
Tools, testing?
Npm
Jest
TypeScript
Rollup
Typescript
DotNetObjectReference type is number | string (int | guid)
Remove .json files from NuGet Packages
{
"compilerOptions": {
"outDir": "./wwwroot",
"target": "ES6",
"moduleResolution": "node",
"lib": [ "ES2016", "DOM"]
},
"exclude": [
"node_modules",
"wwwroot",
"**/*.test.ts"
]
}
tsconfig.json
_content/Namespace/resource.*
Razor Class Library
Assets go in wwwroot
wwwroot becomes => _content/Namespace/*
Do provide minified and standard formats
Example
<script src="_content/BlazorPro.BlazorSize/blazorSize.min.js"></script>
Blazorators?
A project using C# source generators to create JavaScript interop libraries automatically
from web specifications.
https://github.com/IEvangelist/blazorators
https://www.nuget.org/packages?q=dpine+blazor
QUESTIONS
Resources
1. EdCharbeneau.com
• Free Ebook & examples
• GitHub
• Twitter
• Twitch
2. Blogs.Telerik.com

More Related Content

Similar to Writing JavaScript for C# Blazor.pptx

From Node.js to Design Patterns
From Node.js to Design Patterns From Node.js to Design Patterns
From Node.js to Design Patterns Luciano Mammino
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 
Cервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииCервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииArtem Kovardin
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...Ben Teese
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Ben Lesh
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Nativejoshcjensen
 
Javascript call ObjC
Javascript call ObjCJavascript call ObjC
Javascript call ObjCLin Luxiang
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication developmentGanesh Gembali
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Go Mobile with Apache Cordova, Zagreb 2014
Go Mobile with Apache Cordova, Zagreb 2014Go Mobile with Apache Cordova, Zagreb 2014
Go Mobile with Apache Cordova, Zagreb 2014Christian Grobmeier
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScriptersgerbille
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinJava User Group Latvia
 
Async programming on NET
Async programming on NETAsync programming on NET
Async programming on NETyuyijq
 

Similar to Writing JavaScript for C# Blazor.pptx (20)

Android and cpp
Android and cppAndroid and cpp
Android and cpp
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
From Node.js to Design Patterns
From Node.js to Design Patterns From Node.js to Design Patterns
From Node.js to Design Patterns
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Cервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииCервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегии
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Javascript call ObjC
Javascript call ObjCJavascript call ObjC
Javascript call ObjC
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Go Mobile with Apache Cordova, Zagreb 2014
Go Mobile with Apache Cordova, Zagreb 2014Go Mobile with Apache Cordova, Zagreb 2014
Go Mobile with Apache Cordova, Zagreb 2014
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScripters
 
非同期javascriptの過去と未来
非同期javascriptの過去と未来非同期javascriptの過去と未来
非同期javascriptの過去と未来
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
 
Async programming on NET
Async programming on NETAsync programming on NET
Async programming on NET
 

More from Ed Charbeneau

Blazor Stability Testing Tools for Bullet Proof Applications
Blazor Stability Testing Tools for Bullet Proof ApplicationsBlazor Stability Testing Tools for Bullet Proof Applications
Blazor Stability Testing Tools for Bullet Proof ApplicationsEd Charbeneau
 
Secrets of a Blazor Component Artisan (v2)
Secrets of a Blazor Component Artisan (v2)Secrets of a Blazor Component Artisan (v2)
Secrets of a Blazor Component Artisan (v2)Ed Charbeneau
 
Modernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxModernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxEd Charbeneau
 
Modernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxModernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxEd Charbeneau
 
Secrets of a Blazor Component Artisan
Secrets of a Blazor Component ArtisanSecrets of a Blazor Component Artisan
Secrets of a Blazor Component ArtisanEd Charbeneau
 
Goodbye JavaScript Hello Blazor
Goodbye JavaScript Hello BlazorGoodbye JavaScript Hello Blazor
Goodbye JavaScript Hello BlazorEd Charbeneau
 
Razor into the Razor'verse
Razor into the Razor'verseRazor into the Razor'verse
Razor into the Razor'verseEd Charbeneau
 
Giving Clarity to LINQ Queries by Extending Expressions R2
Giving Clarity to LINQ Queries by Extending Expressions R2Giving Clarity to LINQ Queries by Extending Expressions R2
Giving Clarity to LINQ Queries by Extending Expressions R2Ed Charbeneau
 
The future of .NET lightning talk
The future of .NET lightning talkThe future of .NET lightning talk
The future of .NET lightning talkEd Charbeneau
 
Into the next dimension
Into the next dimensionInto the next dimension
Into the next dimensionEd Charbeneau
 
Giving Clarity to LINQ Queries by Extending Expressions
Giving Clarity to LINQ Queries by Extending ExpressionsGiving Clarity to LINQ Queries by Extending Expressions
Giving Clarity to LINQ Queries by Extending ExpressionsEd Charbeneau
 
What is new in Q2 2015
What is new in Q2 2015What is new in Q2 2015
What is new in Q2 2015Ed Charbeneau
 
TelerikNEXT What's new in UI for ASP.NET AJAX
TelerikNEXT What's new in UI for ASP.NET AJAXTelerikNEXT What's new in UI for ASP.NET AJAX
TelerikNEXT What's new in UI for ASP.NET AJAXEd Charbeneau
 
Journey to JavaScript (from C#)
Journey to JavaScript (from C#)Journey to JavaScript (from C#)
Journey to JavaScript (from C#)Ed Charbeneau
 
Don't be a stereotype: Rapid Prototype
Don't be a stereotype: Rapid PrototypeDon't be a stereotype: Rapid Prototype
Don't be a stereotype: Rapid PrototypeEd Charbeneau
 
A crash course in responsive design
A crash course in responsive designA crash course in responsive design
A crash course in responsive designEd Charbeneau
 

More from Ed Charbeneau (19)

Blazor Stability Testing Tools for Bullet Proof Applications
Blazor Stability Testing Tools for Bullet Proof ApplicationsBlazor Stability Testing Tools for Bullet Proof Applications
Blazor Stability Testing Tools for Bullet Proof Applications
 
Secrets of a Blazor Component Artisan (v2)
Secrets of a Blazor Component Artisan (v2)Secrets of a Blazor Component Artisan (v2)
Secrets of a Blazor Component Artisan (v2)
 
Modernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxModernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptx
 
Modernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptxModernizing Web Apps with .NET 6.pptx
Modernizing Web Apps with .NET 6.pptx
 
Blazor Full-Stack
Blazor Full-StackBlazor Full-Stack
Blazor Full-Stack
 
Secrets of a Blazor Component Artisan
Secrets of a Blazor Component ArtisanSecrets of a Blazor Component Artisan
Secrets of a Blazor Component Artisan
 
Goodbye JavaScript Hello Blazor
Goodbye JavaScript Hello BlazorGoodbye JavaScript Hello Blazor
Goodbye JavaScript Hello Blazor
 
Razor into the Razor'verse
Razor into the Razor'verseRazor into the Razor'verse
Razor into the Razor'verse
 
Blazor
BlazorBlazor
Blazor
 
Giving Clarity to LINQ Queries by Extending Expressions R2
Giving Clarity to LINQ Queries by Extending Expressions R2Giving Clarity to LINQ Queries by Extending Expressions R2
Giving Clarity to LINQ Queries by Extending Expressions R2
 
The future of .NET lightning talk
The future of .NET lightning talkThe future of .NET lightning talk
The future of .NET lightning talk
 
Into the next dimension
Into the next dimensionInto the next dimension
Into the next dimension
 
Giving Clarity to LINQ Queries by Extending Expressions
Giving Clarity to LINQ Queries by Extending ExpressionsGiving Clarity to LINQ Queries by Extending Expressions
Giving Clarity to LINQ Queries by Extending Expressions
 
What is new in Q2 2015
What is new in Q2 2015What is new in Q2 2015
What is new in Q2 2015
 
TelerikNEXT What's new in UI for ASP.NET AJAX
TelerikNEXT What's new in UI for ASP.NET AJAXTelerikNEXT What's new in UI for ASP.NET AJAX
TelerikNEXT What's new in UI for ASP.NET AJAX
 
Journey to JavaScript (from C#)
Journey to JavaScript (from C#)Journey to JavaScript (from C#)
Journey to JavaScript (from C#)
 
Refactoring css
Refactoring cssRefactoring css
Refactoring css
 
Don't be a stereotype: Rapid Prototype
Don't be a stereotype: Rapid PrototypeDon't be a stereotype: Rapid Prototype
Don't be a stereotype: Rapid Prototype
 
A crash course in responsive design
A crash course in responsive designA crash course in responsive design
A crash course in responsive design
 

Recently uploaded

Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 

Recently uploaded (20)

Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 

Writing JavaScript for C# Blazor.pptx

  • 2. Ed Charbeneau Author: Pr. Developer Advocate Progress Software, Telerik UI for Blazor “Blazor: A Beginner's Guide” (free) Тwitter: @EdCharbeneau Тwitch: Twitch.tv/EdCharbeneau
  • 3. Why do we need it? Blazor is really, really, new! C# Doesn’t have a full API surface for the Browser’s Web APIs
  • 4.
  • 5. Why do don’t we need it? LocalStorage ◦ dotnet add package Blazored.LocalStorage MediaQueries ◦ dotnet add package BlazorPro.BlazorSize File Uploads ◦ dotnet add package Telerik.UI.for.Blazor • Commercial library .NET 5, 6+ ◦ SEO support, <Head>
  • 6. What’s the JavaScript Interop A Blazor app can invoke JavaScript functions from .NET methods and .NET methods from JavaScript functions.
  • 7. How do we do it? C# API DotNetObjectReference<T> ◦ Value (T instance) ◦ Dispose() IJSRuntime ◦ .InvokeAsync<T>(fname, p) ◦ .InvokeVoidAsync(fname, p) JAVASCRIPT API DotNetObjectReference ◦ number | string (guid) ◦ invokeMethodAsync(fname, p) ◦ dispose Parameters & Values must be JSON serializeable
  • 8. How do we do it? CONVENTION Use namespaces window.namespace.function window.myFoo = { doFoo: function() {} } UNLESS The function already exists on the window object. window.alert Parameters & Values must be JSON serializeable
  • 9. InvokeVoidAsync @inject IJSRuntime js await js.InvokeVoidAsync("myFunction", "Hello"); window.myFunction = (text) => alert(text); JS C#
  • 10. Component Lifecycle Awareness SetParametersAsync() OnInitializedAsync() OnParametersSetAsync() OnAfterRenderAsync(bool firstRender) ShouldRender() Avoid JavaScript interop during Initialization. Because Blazor can utilize Server rendering, JavaScript may not be available. Use OnAfterRenderAsync for initializing JavaScript.
  • 11. Lazy Loaing Modules Lazy<Task<IJSObjectReference>> InvokeAsync<IJSObjectReference> private readonly Lazy<Task<IJSObjectReference>> moduleTask; public MyService(IJSRuntime jsRuntime) { moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/Namespace/module.js").AsTask()); } public async Task Foo() { module.InvokeVoidAsync("method", args) } let module = await import('/modules/module.js'); JS C#
  • 13. Scenarios: One Way Invoke JavaScript from C# Fire and forget No return value private readonly IJSRuntime jsRuntime; private async ValueTask Cancel() => await jsRuntime.InvokeVoidAsync($“namespace.functionName“, parameters); C# JS window.alert Void C# window.namespace = { function: functionName() } JS
  • 14. Scenarios: Round Trip (C# <-> JS) Invoke JavaScript from C# Return value C# JS invokeMethod Value string name = await js.InvokeAsync<string>("prompt", "What is your name?"); Result = $"Your name is: {name}"; C#
  • 15. Scenarios: Round Trip (JS <-> C#) [JSInvokable] Attribute Invoke C# Static Method from JS JS C# RaiseEvent Value [JSInvokable] [JSInvokable] public static Task<int[]> ReturnArrayAsync() Task.FromResult(new int[] { 1, 2, 3 }); returnArrayAsyncJs: function () { DotNet.invokeMethodAsync(‘namespace', 'ReturnArrayAsync') .then(data => { data.push(4); console.log(data); }); }, C# JS
  • 16. Scenarios: Round-Trip Callback Invoke JavaScript from .NET Invoke C# Instance Method from JS DotNetObjectReference Dispose, dispose, dispose C# JS Function.callbac k Value R R Instance.method
  • 17. Scenarios: Round-Trip Callback public class GeoLocation { public async ValueTask GetCurrentPosition(...) => await js.InvokeVoidAsync ("blazorGeolocation.getCurrentPosition", DotNetObjectReference.Create(this), options); [JSInvokable] public void RaiseOnGetPosition(Position p) => [JSInvokable] public void RaiseOnGetPositionError(Error err) => window.blazorGeolocation = { getCurrentPosition: function (geolocationRef, options) { navigator.geolocation .getCurrentPosition(onSuccess, onError, options); }, function onSuccess(result) { return geolocationRef .invokeMethodAsync('RaiseOnGetPosition’, blazorGeolocation.toSerializeable(result)); }; function onError(er) { return geolocationRef .invokeMethodAsync('RaiseOnGetPositionError’, er.code); }; }; JS C#
  • 18. Scenarios: Round-Trip Callback public class GeoLocation { public async ValueTask GetCurrentPosition(...) => await js.InvokeVoidAsync ("blazorGeolocation.getCurrentPosition", DotNetObjectReference.Create(this), options); [JSInvokable] public void RaiseOnGetPosition(Position p) => [JSInvokable] public void RaiseOnGetPositionError(Error err) => window.blazorGeolocation = { getCurrentPosition: function (geolocationRef, options) { navigator.geolocation .getCurrentPosition(onSuccess, onError, options); }, function onSuccess(result) { return geolocationRef .invokeMethodAsync('RaiseOnGetPosition’, blazorGeolocation.toSerializeable(result)); }; function onError(er) { return geolocationRef .invokeMethodAsync('RaiseOnGetPositionError’, er.code); }; }; JS C#
  • 19. Scenarios: Round-Trip Callback public class GeoLocation { public async ValueTask GetCurrentPosition(...) => await js.InvokeVoidAsync ("blazorGeolocation.getCurrentPosition", DotNetObjectReference.Create(this), options); [JSInvokable] public void RaiseOnGetPosition(Position p) => [JSInvokable] public void RaiseOnGetPositionError(Error err) => window.blazorGeolocation = { getCurrentPosition: function (geolocationRef, options) { navigator.geolocation .getCurrentPosition(onSuccess, onError, options); }, function onSuccess(result) { return geolocationRef .invokeMethodAsync('RaiseOnGetPosition’, blazorGeolocation.toSerializeable(result)); }; function onError(er) { return geolocationRef .invokeMethodAsync('RaiseOnGetPositionError’, er.code); }; }; JS C#
  • 20. Scenarios: Round-Trip Callback public class GeoLocation { public async ValueTask GetCurrentPosition(...) => await js.InvokeVoidAsync ("blazorGeolocation.getCurrentPosition", DotNetObjectReference.Create(this), options); [JSInvokable] public void RaiseOnGetPosition(Position p) => [JSInvokable] public void RaiseOnGetPositionError(Error err) => window.blazorGeolocation = { getCurrentPosition: function (geolocationRef, options) { navigator.geolocation .getCurrentPosition(onSuccess, onError, options); }, function onSuccess(result) { return geolocationRef .invokeMethodAsync('RaiseOnGetPosition’, blazorGeolocation.toSerializeable(result)); }; function onError(er) { return geolocationRef .invokeMethodAsync('RaiseOnGetPositionError’, er.code); }; }; JS C#
  • 21. Pub-Sub JS C# DOM EventA DOM EventB Channel Component (A) Component (AB) Component (B) Component (AB)
  • 22. Pub-Sub: Init JS C# Channel Component (A) .addEventListener DOM EventA
  • 23. Pub-Sub: De-dupe JS C# Channel Component (A) .addEventListener DOM EventA DOM EventB Component (AB) DOM EventA
  • 24. Pub-Sub: Dispose JS C# DOM EventA DOM EventB Channel Component (A) Component (AB) Component (B) Component (AB) .removeEventListener .Dispose
  • 25. Pub-Sub: Developer Experience JS C# DOM EventA DOM EventB Channel Component (A) Component (AB) Component (B) Component (AB) <MediaQueryList> <MediaQuery> <MediaQuery> <MediaQuery> <MediaQuery> mediaQueryLists: MediaQueryListItem[] MediaQueryListItem { id: number | string; dotnetCallback: (ev: MediaQueryListEvent) mediaQueries: MediaQueryList[]; }
  • 26. Scenario: Throttle Events (Blazor Server) A B C D E F G A D G throttleTime(n_ms)
  • 27. Scenario: Throttle Events (Blazor Server) this.reportRate = 300; this.throttleResizeHandler = () => { clearTimeout(this.throttleResizeHandlerId); this.throttleResizeHandlerId = window.setTimeout(this.resizeHandler, this.options.reportRate); };
  • 29. Typescript DotNetObjectReference type is number | string (int | guid) Remove .json files from NuGet Packages { "compilerOptions": { "outDir": "./wwwroot", "target": "ES6", "moduleResolution": "node", "lib": [ "ES2016", "DOM"] }, "exclude": [ "node_modules", "wwwroot", "**/*.test.ts" ] } tsconfig.json
  • 30. _content/Namespace/resource.* Razor Class Library Assets go in wwwroot wwwroot becomes => _content/Namespace/* Do provide minified and standard formats Example <script src="_content/BlazorPro.BlazorSize/blazorSize.min.js"></script>
  • 31. Blazorators? A project using C# source generators to create JavaScript interop libraries automatically from web specifications. https://github.com/IEvangelist/blazorators https://www.nuget.org/packages?q=dpine+blazor
  • 32. QUESTIONS Resources 1. EdCharbeneau.com • Free Ebook & examples • GitHub • Twitter • Twitch 2. Blogs.Telerik.com