### Async and Sync Function Examples Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/SpawnDev.BlazorJS.Demo/wwwroot/index.html Demonstrates basic async/await patterns and synchronous function returns. ```javascript async function WillFail() { console.log('> WillFail'); await Sleep(2000); var b = gg(); return b; } function NotAsync() { console.log('> NotAsync'); return null; } async function WaitForIt(task) { console.log('> WaitForIt', task); var ret = await task; console.log('> WaitForIt', ret); } ``` -------------------------------- ### Use LocalStorage with BlazorJS Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md This example demonstrates how to interact with the browser's LocalStorage API using BlazorJS. It shows how to get a Storage object, set an item, and retrieve an item. ```cs [Inject] BlazorJSRuntime JS { get; set; } override void OnInitialized() { using Storage localStorage = JS.Get("localStorage"); localStorage.SetItem("myKey", "myValue"); var myValue = localStorage.GetItem("myKey"); // myValue == "myValue" } ``` -------------------------------- ### Basic JavaScript Interop Examples Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Demonstrates common JavaScript interop operations using BlazorJSRuntime, including getting and setting properties, calling methods, and handling events. Ensure BlazorJSRuntime is properly injected and initialized. ```cs // Get and Set var innerHeight = JS.Get("window.innerHeight"); JS.Set("document.title", "Hello World!"); // Call var item = JS.Call("localStorage.getItem", "itemName"); JS.CallVoid("addEventListener", "resize", Callback.Create(() => Console.WriteLine("WindowResized"), _callBacks)); // Attach events using var window = JS.Get("window"); window.OnOffline += Window_OnOffline; // AddEventListener and RemoveEventListener are supported on all EventTarget objects window.AddEventListener("resize", Window_OnResize, true); window.RemoveEventListener("resize", Window_OnResize, true); ``` -------------------------------- ### Interact with HTMLVideoElement in Blazor Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md This example shows how to use the HTMLVideoElement class from SpawnDev.BlazorJS to control and get information from a video element in Blazor. It includes handling metadata loading and errors. ```cs @page "/HTMLVideoElementExample" @implements IDisposable
Source: @videoName
Duration: @duration.ToString()
Metadata: @metadata
@foreach (var video in videos) { }
    @((MarkupString)log)
@code { [Inject] BlazorJSRuntime JS { get; set; } ElementReference? videoElRef; HTMLVideoElement? videoEl = null; TimeSpan duration = TimeSpan.Zero; string videoName = ""; string metadata = ""; string log = ""; Dictionary videos = new Dictionary { { "Elephants Dream", "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" }, { "Big Buck Bunny", "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" }, { "Tears Of Steel", "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4" }, { "Sintel", "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4" }, { "None", "" }, }; protected override void OnAfterRender(bool firstRender) { if (firstRender) { videoEl = (HTMLVideoElement)videoElRef!; videoEl.OnLoadedMetadata += VideoEl_OnLoadedMetadata; videoEl.OnAbort += VideoEl_OnAbort; videoEl.OnError += VideoEl_OnError; } } void SetSource(string name, string source) { if (videoEl == null) return; Log($"SetSource: {name}"); videoName = name; videoEl.Src = source; StateHasChanged(); } void VideoEl_OnLoadedMetadata() { Log("VideoEl_OnLoadedMetadata"); metadata = $"{videoEl!.VideoWidth}x{videoEl!.VideoHeight}"; duration = TimeSpan.FromSeconds(videoEl!.Duration ?? 0); StateHasChanged(); } void VideoEl_OnError() { Log("VideoEl_OnError"); } void VideoEl_OnAbort() { Log("VideoEl_OnAbort"); metadata = $"{videoEl!.VideoWidth}x{videoEl!.VideoHeight}"; duration = TimeSpan.FromSeconds(videoEl!.Duration ?? 0); StateHasChanged(); } public void Dispose() { if (videoEl != null) { videoEl.OnLoadedMetadata -= VideoEl_OnLoadedMetadata; videoEl.OnAbort -= VideoEl_OnAbort; videoEl.OnError -= VideoEl_OnError; videoEl.Dispose(); videoEl = null; } } void Log(string message) { log += $"{message}
"; } } ``` -------------------------------- ### Add and Initialize BlazorJSRuntime in Program.cs Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Configure your Blazor application to use BlazorJSRuntime by adding the service and initializing it with BlazorJSRunAsync. This setup is required for all BlazorJS functionalities. ```cs // ... other usings using SpawnDev.BlazorJS; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); // Add SpawnDev.BlazorJS.BlazorJSRuntime builder.Services.AddBlazorJSRuntime(); // build and Init using BlazorJSRunAsync (instead of RunAsync) await builder.Build().BlazorJSRunAsync(); ``` -------------------------------- ### Serialize Func for JavaScript Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Example of passing a Func to JavaScript and reading it back, ensuring proper disposal of created objects. ```csharp int testValue = 42; var origFunc = new Func((val) => { return val; }); // set a global Javascript var to our Func // if this is the first time this Func is passed to Javascript a Callback will be created and associated to this Func for use in future serialization // the auto created Callback must be disposed by calling the extension method Func.DisposeJS() JS.Set("_funcCallback", origFunc); // read back in our Func as an Func // internally a Javascript Function reference is created and associated with this Func. // the auto created Function must be disposed by calling the extension method Func.DisposeJS() var readFunc = JS.Get>("_funcCallback"); var readVal = readFunc(testValue); if (readVal != testValue) throw new Exception("Unexpected result"); // dispose the Function created and associated with the read Func readFunc.DisposeJS(); // dispose the Callback created and associated with the original Func origFunc.DisposeJS(); ``` -------------------------------- ### Performing HTTP Requests with Fetch API Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Shows how to perform GET and POST requests, handle JSON responses, and download binary data as Blobs or ArrayBuffers. ```csharp [Inject] BlazorJSRuntime JS { get; set; } async Task FetchExample() { // Simple GET request using var response = await JS.Fetch("https://api.example.com/data"); if (response.Ok) { var text = await response.Text(); Console.WriteLine(text); } // GET request with response as JSON using var jsonResponse = await JS.Fetch("https://api.example.com/users"); var users = await jsonResponse.Json>(); // POST request with options using var postResponse = await JS.Fetch("https://api.example.com/users", new FetchOptions { Method = "POST", Headers = new Dictionary { { "Content-Type", "application/json" } }, Body = JsonSerializer.Serialize(new { name = "John", email = "john@example.com" }) }); // Download as Blob using var blobResponse = await JS.Fetch("https://example.com/image.png"); using var blob = await blobResponse.Blob(); var url = URL.CreateObjectURL(blob); // Download as ArrayBuffer using var bufferResponse = await JS.Fetch("https://example.com/binary"); using var buffer = await bufferResponse.ArrayBuffer(); var bytes = buffer.ToArray(); } public class User { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } } ``` -------------------------------- ### Custom JSObject Wrapper for Audio Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Example of creating a custom C# class that wraps a JavaScript object, providing strongly-typed methods for interaction. ```cs public class Audio : JSObject { // deserialization constructor public Audio(IJSInProcessObjectReference _ref) : base(_ref) { } // constructor that accepts a string url public Audio(string url) : base(JS.New("Audio", url)) { } // method decalaration public void Play() => JSRef.CallVoid("play"); } ``` ```cs var audio = new Audio("https://some_audio_online"); audio.Play(); ``` -------------------------------- ### Serialize Action for JavaScript Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Example of passing an Action to JavaScript and disposing of the associated Callback. ```csharp var tcs = new TaskCompletionSource(); var callback = () => { tcs.TrySetResult(true); }; JS.CallVoid("setTimeout", callback, 100); await tcs.Task; callback.DisposeJS(); ``` -------------------------------- ### Access Camera and Microphone with MediaDevices Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Access the user's camera and microphone using the Navigator.MediaDevices API. Enumerate available devices and request media streams for video and audio. Includes an example for requesting screen capture. ```csharp [Inject] BlazorJSRuntime JS { get; set; } async Task MediaDevicesExample() { using var navigator = JS.Get("navigator"); using var mediaDevices = navigator.MediaDevices; // Enumerate all media devices var devices = await mediaDevices.EnumerateDevices(); foreach (var device in devices) { Console.WriteLine($"{device.Kind}: {device.Label} (ID: {device.DeviceId})"); device.Dispose(); } // Request webcam access try { using var stream = await mediaDevices.GetUserMedia(new MediaStreamConstraints { Video = true, Audio = true }); // Get video tracks var videoTracks = stream.GetVideoTracks(); foreach (var track in videoTracks) { Console.WriteLine($"Video track: {track.Label}"); track.Dispose(); } // Assign stream to video element using var videoEl = JS.Get("document.querySelector('video')"); videoEl.SrcObject = stream; await videoEl.Play(); } catch (Exception ex) { Console.WriteLine($"Error accessing camera: {ex.Message}"); } // Request screen capture try { using var displayStream = await mediaDevices.GetDisplayMedia(new DisplayMediaStreamOptions { Video = true }); // Use displayStream for screen recording/sharing } catch (Exception ex) { Console.WriteLine($"Screen capture denied: {ex.Message}"); } } ``` -------------------------------- ### Define JSObject Class Members Source: https://github.com/lostbeard/spawndev.blazorjs/blob/main/README.md Example of defining properties and methods within a class derived from JSObject or its subclasses. ```csharp public class Window : EventTarget { // all JSObject types must have this constructor public Window(IJSInProcessObjectReference _ref) : base(_ref) { } // here is a property with both getter and setter public string? Name { get => JSRef.Get("name"); set => JSRef.Set("name", value); } // here is a read only property that returns another JSObject type public Storage LocalStorage => JSRef.Get("localStorage"); // here are methods public long SetTimeout(Callback callback, double delay) => JSRef.Call("setTimeout", callback, delay); public void ClearTimeout(long requestId) => JSRef.CallVoid("clearTimeout", requestId); // ... } ``` -------------------------------- ### Retrieve JavaScript Properties Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Use Get to access properties via dot notation, including support for null-conditional access and type checking. ```csharp [Inject] BlazorJSRuntime JS { get; set; } void GetPropertiesExample() { // Get simple property values var innerHeight = JS.Get("window.innerHeight"); var innerWidth = JS.Get("window.innerWidth"); var title = JS.Get("document.title"); var href = JS.Get("window.location.href"); // Get property as JSObject wrapper using var window = JS.Get("window"); using var document = JS.Get("document"); using var localStorage = JS.Get("localStorage"); // Null-conditional access - returns null if path doesn't exist var size = JS.Get("fruit.options?.size"); // size == null if fruit.options is undefined // Check if property is undefined var isUndefined = JS.IsUndefined("window.someUndefinedProperty"); // isUndefined == true // Get typeof a property var typeOf = JS.TypeOf("window.localStorage"); // typeOf == "object" } ``` -------------------------------- ### Register and Initialize BlazorJSRuntime Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Register the service in Program.cs and use BlazorJSRunAsync to initialize the runtime. ```csharp using SpawnDev.BlazorJS; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); // Add the BlazorJSRuntime service builder.Services.AddBlazorJSRuntime(); // Build and initialize using BlazorJSRunAsync (instead of RunAsync) await builder.Build().BlazorJSRunAsync(); ``` -------------------------------- ### Managing Browser Storage Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Demonstrates using the Storage wrapper for localStorage and sessionStorage, including JSON serialization for complex objects. ```csharp [Inject] BlazorJSRuntime JS { get; set; } void StorageExample() { // Get localStorage using var localStorage = JS.Get("localStorage"); // Basic string storage localStorage.SetItem("username", "John"); var username = localStorage.GetItem("username"); // Check if key exists if (localStorage.ItemExists("username")) { Console.WriteLine($"User: {localStorage.GetItem("username")}"); } // Store and retrieve JSON objects var settings = new AppSettings { Theme = "dark", Language = "en", FontSize = 14 }; localStorage.SetJSON("settings", settings); var loadedSettings = localStorage.GetJSON("settings"); // Get all keys var keys = localStorage.GetItemKeys(); Console.WriteLine($"Stored keys: {string.Join(", ", keys)}"); // Get number of items var count = localStorage.Length; // Remove specific item localStorage.RemoveItem("username"); // Clear all items localStorage.Clear(); // SessionStorage works the same way using var sessionStorage = JS.Get("sessionStorage"); sessionStorage.SetItem("tempData", "session value"); } public class AppSettings { public string Theme { get; set; } public string Language { get; set; } public int FontSize { get; set; } } ``` -------------------------------- ### Working with JavaScript Promises Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Demonstrates wrapping JavaScript Promises, creating Promises from .NET Tasks, and handling timeouts or Web Locks. ```csharp [Inject] BlazorJSRuntime JS { get; set; } async Task PromiseExample() { // Call async JavaScript method that returns a Promise var result = await JS.CallAsync("fetchData", "https://api.example.com"); // Work with Promise directly using var promise = JS.Call>("fetch", "https://api.example.com") .Then(response => response.Text()); var text = await promise.ThenAsync(); // Create Promise from .NET async method var netPromise = new Promise(async () => { await Task.Delay(1000); return "Hello from .NET async!"; }); JS.Set("window.myPromise", netPromise); // Create Promise from Task var taskSource = new TaskCompletionSource(); var taskPromise = new Promise(taskSource.Task); JS.Set("window.taskPromise", taskPromise); // Later resolve it: taskSource.TrySetResult(42); // Promise with timeout using var timedPromise = JS.Call>("fetch", "https://slow-api.com"); try { var response = await timedPromise.ThenAsync(timeoutMS: 5000); } catch (Exception ex) { Console.WriteLine("Request timed out"); } // Use Promise for Web Locks API using var navigator = JS.Get("navigator"); using var locks = navigator.Locks; using var lockPromise = locks.Request("my_lock", Callback.CreateOne((Lock lockObj) => new Promise(async () => { Console.WriteLine("Lock acquired"); await Task.Delay(2000); Console.WriteLine("Lock released"); }))); } ``` -------------------------------- ### JS.New - Creating JavaScript Objects Source: https://context7.com/lostbeard/spawndev.blazorjs/llms.txt Explains how to instantiate new JavaScript objects and classes directly from Blazor using the `New` method. ```APIDOC ## JS.New - Creating JavaScript Objects The `New` method creates new instances of JavaScript classes. Pass the class name and constructor arguments to instantiate objects directly from Blazor. ### Method `JS.New(string className, params object[] args)` `JS.New(string className, params object[] args)` ### Description This method allows you to create new JavaScript objects. `New` returns a strongly-typed reference of type `T`. If `T` is not specified, it returns an untyped `IJSObjectReference`. ### Request Example (C#) ```csharp [Inject] BlazorJSRuntime JS { get; set; } void CreateObjectsExample() { // Create a new Date object using var date = JS.New("Date"); Console.WriteLine($"Current time: {date.ToISOString()}"); // Create with constructor arguments using var specificDate = JS.New("Date", 2024, 0, 15); // Month is 0-indexed // Create a Worker using var worker = JS.New("Worker", "/js/myWorker.js"); // Create a Blob byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello World"); using var blob = JS.New("Blob", new object[] { data }, new { type = "text/plain" }); // Create an Audio element using var audio = JS.New