Your C++ code can evaluate arbitrary strings of JavaScript and call functions defined on a page (with type-converted results).

## Example HTML

The examples in this guide use this HTML snippet:

```html
<html>
  <head>
    <script>
      var score = 42;

      function ShowMessage(message) {
        if (!message) throw new Error("empty message");
        document.getElementById('msg').innerHTML = message;
      }

      function computeTotal(a, b) {
        return a + b;
      }
    </script>
  </head>
  <body>
    <div id="msg"></div>
  </body>
</html>
```

## Getting the Page's Context

Every call into a page goes through its [`js::Context`](/api/cpp/2_0_0/classultralight_1_1js_1_1_context.html). You can get it from a View via `LoadListener::OnDOMReady()`:

```cpp
// Inherited from LoadListener::OnDOMReady:
void MyApp::OnDOMReady(View* caller, uint64_t frame_id, bool is_main_frame,
                       const String& url) {
  if (!is_main_frame)
    return;

  // Get the context of the View's main frame.
  js::Context ctx(caller);
}
```

> 📘 When to Get the Context
>
> Use `OnDOMReady()` for calls that need the page's DOM or its scripts. If native code needs to set up state before the page's own scripts run, get the context in `OnWindowObjectReady()` instead— it fires before `OnDOMReady()`. See [Handling View Events](/docs/2.0/handling-view-events) for details on both callbacks.

### One Context per Navigation

Each page gets its own context. After every navigation you'll need to get a new one.

The old context and every value from it are then no longer valid. Anything you do with them fails safely instead of crashing.

> 🚧 Stay on the Renderer's Thread
>
> Every call into the page must run on the Renderer's thread.

## Calling a Function

Index the context with the function's name and call it:

```cpp
ctx["ShowMessage"]("Howdy!");
```

Indexing `ctx` reads a property of the page's global object (ie, `window`).

## Getting Results

Calls to JavaScript functions return `js::Result` which can be converted to a C++ type. (See [Async Callbacks](/docs/2.0/async-callbacks) to wait for a function that returns a Promise.)

### With a Fallback

Use `js::Or()` to convert a value or a call's result to a C++ type with a fallback:

```cpp
double score = js::Or(ctx["score"], 0.0);
double total = js::Or(ctx["computeTotal"](3, 4), 0.0);
```

You get the fallback if the property is missing, the call fails, or the value isn't already a number (conversion is strict and never coerces).

### Type-Checked Call Results

Use `Invoke<T>()` when you want to call a JavaScript function and enforce a specific C++ return type. It returns a `js::Result` that holds either the converted value or a `js::Error`:

```cpp
js::Result<double> total = ctx["computeTotal"].Invoke<double>(3, 4);
if (total)
  UseTotal(*total);
else if (total.error().is_page_gone())
  return;                              // the page is gone (nothing to report)
else
  Log(total.error().message());        // it threw or didn't return a number
```

> 👍 Ignored Exceptions Are Never Lost
>
> All JavaScript API errors or exceptions encountered are written to `Logger` when developer mode is active (see [Developer Mode and Diagnostics](/docs/2.0/developer-mode-and-diagnostics)).

## Keeping a Function for Later

Store a function in a `js::Value` to call it later:

```cpp
js::Value show = ctx["ShowMessage"];

// Later:
if (show.IsCallable())
  show("Howdy again!");
```

> 📘 The Value of `this`
>
> Calling a stored function sets `this` to the global object. Use `show.InvokeOn(object, args...)` to call it as a method of some object instead.

## Running a Script

### Evaluating a Script

Call `ctx.Evaluate()` to run a script on the page:

```cpp
js::Result<js::Value> result = ctx.Evaluate("score * 2");  // holds 84
```

The result holds the script's value as a `js::Value` (or the error if the script threw).

### Converting the Result

Use `Evaluate<T>()` to convert the script's value to a C++ type. Wrap it in `js::Or()` for a fallback:

```cpp
double doubled = js::Or(ctx.Evaluate<double>("score * 2"), 0.0);
```

### Evaluating Without a Context

Call `View::EvaluateScript()` on the View when a string is all you need:

```cpp
String title = view->EvaluateScript("document.title");
```

The result is converted to a string (`undefined` becomes `"undefined"`). The optional second argument (a `String*`) receives the message if the script throws.

## Handing the Page a Callback

`ctx.MakeFunction()` creates a JavaScript function that runs your C++ callback:

```cpp
js::Value cb = ctx.MakeFunction("onTick", [](double dt) { /* ... */ });
ctx["registerTick"](cb);
```

The page can keep the function and call it whenever it likes:

```js
let tick = null;
function registerTick(cb) { tick = cb; }

// Later: runs the C++ callback with dt = 16.7.
tick(16.7);
```

Your C++ callback never runs if the page passes an argument of the wrong type (eg, a string for `dt`). The page gets a `TypeError` instead.

The callback must be synchronous (it returns a value or a `js::Result`).

> 🚧 Callback Lifetime
>
> The callback is destroyed on the Renderer's thread after the page's function is garbage collected. Use a `js::API` binding instead for a function that must survive navigation or run asynchronously (see [Extending JavaScript with Native API](/docs/2.0/extending-javascript-with-native-api)).
