SlideShare a Scribd company logo
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

Android and cpp
Android and cppAndroid and cpp
Android and cpp
Joan Puig Sanz
 
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 2013
Laurent_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 2016
Ben Lesh
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
joshcjensen
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
Javascript call ObjC
Javascript call ObjCJavascript call ObjC
Javascript call ObjC
Lin Luxiang
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
Ganesh 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
 
How to React Native
How to React NativeHow to React Native
How to React Native
Dmitry Ulyanov
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett 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 2014
Christian Grobmeier
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScriptersgerbille
 
非同期javascriptの過去と未来
非同期javascriptの過去と未来非同期javascriptの過去と未来
非同期javascriptの過去と未来
Taketoshi 青野健利
 
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
Thierry 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 Buzdin
Java User Group Latvia
 
Async programming on NET
Async programming on NETAsync programming on NET
Async programming on NET
yuyijq
 

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 Applications
Ed 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.pptx
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.pptx
Ed Charbeneau
 
Blazor Full-Stack
Blazor Full-StackBlazor Full-Stack
Blazor Full-Stack
Ed Charbeneau
 
Secrets of a Blazor Component Artisan
Secrets of a Blazor Component ArtisanSecrets of a Blazor Component Artisan
Secrets of a Blazor Component Artisan
Ed Charbeneau
 
Goodbye JavaScript Hello Blazor
Goodbye JavaScript Hello BlazorGoodbye JavaScript Hello Blazor
Goodbye JavaScript Hello Blazor
Ed Charbeneau
 
Razor into the Razor'verse
Razor into the Razor'verseRazor into the Razor'verse
Razor into the Razor'verse
Ed Charbeneau
 
Blazor
BlazorBlazor
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
Ed Charbeneau
 
The future of .NET lightning talk
The future of .NET lightning talkThe future of .NET lightning talk
The future of .NET lightning talk
Ed Charbeneau
 
Into the next dimension
Into the next dimensionInto the next dimension
Into the next dimension
Ed 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 Expressions
Ed Charbeneau
 
What is new in Q2 2015
What is new in Q2 2015What is new in Q2 2015
What is new in Q2 2015
Ed 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 AJAX
Ed Charbeneau
 
Journey to JavaScript (from C#)
Journey to JavaScript (from C#)Journey to JavaScript (from C#)
Journey to JavaScript (from C#)
Ed Charbeneau
 
Refactoring css
Refactoring cssRefactoring css
Refactoring css
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 Prototype
Ed Charbeneau
 
A crash course in responsive design
A crash course in responsive designA crash course in responsive design
A crash course in responsive design
Ed 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

Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 

Recently uploaded (20)

Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 

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