I'm Andrew Hoefling, and I work for FileOnQ as a Lead Software Engineer building mobile technologies for Government, Financial and First Responders using Xamarin. 

 

Uno Platform WASM Invoke JavaScript


The Uno Platform Getting Started blog series is a blog series that I put together for October of 2020. It contains several articles that will help you get started building scalable enterprise applications in Uno Platform. Be sure to checkout all the blogs in the series by heading to the 1st article - Uno Platform Getting Started Series

When working with Uno Platform targetting WASM (Web Assembly) you sometimes need to integrate with existing javascript libraries. The team at Uno Platform have built an amazing platform and it is very simple to invoke any type of javascript library that might be loaded on the page.

This is a very special blog because the architect from Uno Platform WASM (Carl de Billy) provided additional notes and details. Look for special Notes from the Architect

Add JavaScript

You will need to add your JavaScript code to the WASM project head in your Uno Platform solution. If you explore the contents of the project there is already a folder called WasmScripts.

  1. Add a new .js to this folder and call it MyCustomScripts.js.
  2. Right-Click on the file and go to properties
  3. Under Build Action select Embedded Resource

Note from the Architect

You can do it manually by pressing F4 and change the BuildAction to
EmbeddedResource, or by changing it in the csproj directly.  Could
also be a globing… maybe we should change the template to already
have something like this: 

<EmbeddedResource Include="WasmScripts\**\*.js" />
https://github.com/unoplatform/uno/blob/0890aa45ce1ba5c92d8d4719e964a1f086f1be36/src/Uno.UI/Uno.UI.Wasm.csproj#L36

Advanced Tip:
By default, if you change your .js file and press F5, VS won’t detect
the change and won’t recompile your project.  To fix that, you should
also add your .js to the UpToDateCheckInput like this:

<UpToDateCheckInput Include="WasmScripts\MyCustomScripts.js" />

Once you have the new file add the following JavaScript function.

function helloWorld() {
    alert('Hello World from native JavaScript');
}

Our JavaScript function is pretty simple, we just want to display a native browser alert message to the user when it is invoked.

Add Button to MainPage

Let's make our Uno App interactive and add a Click Me button to the MainPage.xaml that will invoke the custom helloWorld() function when invoked. Open up the MainPage.xaml and add a Button to the view. Don't forget to configure an event listener to process some C# code after the button is clicked.

MainPage.xaml

<Page
    x:Class="InvokeJavascriptSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
		<TextBlock Text="Hello, world!" Margin="20" FontSize="30" />
        <Button Content="Click Me" Tapped="Button_Tapped"  />
    </Grid>
</Page>

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    private void Button_Tapped(object sender, RoutedEventArgs e)
    {
        // TODO - Invoke JS code here
    }
}

Invoke JavaScript Code

Everything is in place and we can look at invoking the JavaScript file that we included in the WASM project head. If you are unsure how to invoke platform specific code in C# you should check out my blog on this topic or read the Uno Platform docs (which are really great).

There is an extension method that allows you to execute javascript from anywhere. There is no need for platform specific code as this API handles it all for us.

this.ExecuteJavascript("HelloWorld();");

That's it!

You can now launch your app using the WASM target and tap the button. It should display a native browser alert window.

It is recommended to use the extension method ExecuteJavascript. If you are unable to use it because of the version of Uno Platform you can always fallback to the previous technique 👇

Another Way - The Previous Technique

In previous versions of Uno Platform you would need to use the WebAssemblyRuntime to invoke the JS. If you don't have access to the extension method, you can always fallback to this technique.

To start add a #if statement at the top of the file to include special WASM specific namespaces.

#if __WASM__
using Uno.Foundation;
#endif

Once that is completed we can invoke the JavaScript in our Button_Tapped event handler using a similar #if statement.

private void Button_Tapped(object sender, RoutedEventArgs e)
{
#if __WASM__
    WebAssemblyRuntime.InvokeJS("helloWorld()");
#endif
}

This is what your entire MainPage.xaml.cs should look like.

Conclusion

This article covers the basics of invoking JavaScript from the WASM (Web Assembly) project head in an Uno Platform app. There are a lot of possibilities here including referencing libraries and advanced interopability scenarios. If you had any challenges with getting this setup, take a look at my code sample on GitHub.

-Happy Coding


Share

Tags

WASMWeb AssemblyJavaScript.NET