Hace poco, un alumno de mi curso de Blazor en CampusMVP me preguntaba si, para seguir con las viejas costumbres, desde Blazor Server era posible escribir en la consola del navegador.
Aunque no tiene demasiado sentido hacerlo dado que disponemos de buenas herramientas de depuración, me pareció un ejemplo interesante para aplicar los mecanismos de interoperación de Blazor con JavaScript. Además, quizás interese a alguien más, así que vamos a ver por aquí cómo hacerlo.
Pero antes de meternos en faena, vale la pena decir que lo que veremos no es específico de Blazor Server, sino que también podremos usarlo en Blazor WebAssembly. Los mecanismos básicos de interoperación con JavaScript son idénticos, por lo que en este post veremos cómo implementar un código válido para ambos tipos de hosting.
Enviar mensajes a la consola del navegador, versión básica
Como vimos hace tiempo, la interfaz IJSRuntime
ofrece una vía para ejecutar código JavaScript desde C# en nuestros componentes o servicios Blazor.
Basta con inyectar una instancia de este tipo en nuestra clase, y podremos realizar invocaciones directas de código que vive en el lado del cliente, independientemente de si lo estamos ejecutando en el servidor (Blazor Server) o en el cliente (Blazor WebAssembly).
De esta forma, si queremos escribir en la consola, simplemente debemos usar el método InvokeVoidAsync()
como se muestra en el siguiente componente Counter.razor
:
@page "/counter"
@inject IJSRuntime JsRuntime
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private async Task IncrementCount()
{
currentCount++;
await JsRuntime.InvokeVoidAsync("console.log", "Yepa! " + currentCount);
}
}
Observad que usamos
InvokeVoidAsync()
porque el método JavaScriptconsole.log()
no devuelve ningún valor.
En tiempo de ejecución, la pulsación del botón hará que vayan apareciendo mensaje en la consola del navegador, como se muestra en la siguiente imagen:
De la misma forma que llamamos a console.log()
de JavaScript, podríamos invocar otros métodos interesantes como error()
, warn()
, info()
u otros.
Por ejemplo, si insertásemos el siguiente código en el ejemplo anterior, podríamos ver en consola el volcado del objeto .NET que estamos enviando en una traza de error:
private async Task IncrementCount()
{
currentCount++;
await JsRuntime.InvokeVoidAsync("console.log", "Yepa! " + currentCount);
if (currentCount > 10)
{
var arg = new { error = "Too much clicks", count = currentCount};
await JsRuntime.InvokeVoidAsync("console.error", arg);
}
}
La consola del navegador como servicio
En el ejemplo anterior hemos visto que podemos escribir a la consola del navegador desde C# de forma muy sencilla, aunque podríamos mejorarlo un poco si, en lugar de hacerlo inline, extraemos esta funcionalidad a un servicio que podría ser reutilizado en distintos puntos de la aplicación.
Esto podemos verlo en el siguiente bloque de código, donde definimos una clase llamada ConsoleServices
sobre la que creamos métodos que mapean directamente los métodos del objeto console
de JavaScript:
public class ConsoleServices
{
private readonly IJSRuntime _JsRuntime;
public ConsoleServices(IJSRuntime js)
{
_JsRuntime = js;
}
public ValueTask Log(params object[] args)
{
return _JsRuntime.InvokeVoidAsync("console.log", args);
}
public ValueTask Error(params object[] args)
{
return _JsRuntime.InvokeVoidAsync("console.error", args);
}
// .. otros métodos del objeto console de JavaScript
}
Antes de usar el servicio, debemos registrarlo en el inyector de dependencias de Blazor. Tanto en Server como en WebAssembly tendremos que insertar en el archivo Program.cs
la siguiente línea:
builder.Services.AddScoped<ConsoleServices>();
Y a partir de aquí, ya podremos utilizar el servicio en cualquier otro servicio o componente de la aplicación, como muestra la siguiente versión retocada del componente Counter.razor
que vimos más arriba:
@page "/counter"
@inject ConsoleServices Console
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
Console.Log("Dale! " + currentCount);
}
}
Publicado en: www.variablenotfound.com.
Publicado por José M. Aguilar a las 8:05 a. m.
Etiquetas: blazor, blazorinterop, blazorserver, blazorwasm
2 Comentarios:
Si quisiéramos invocar window.screen que no tiene argumentos usando el Console Service.
¿Cómo se haría?
Hola!
Entiendo que te refieres a retornar el contenido de un objeto como window.screen, ¿verdad? En este caso, no se trata de una función, por lo que no puedes llamarla usando los métodos Invoke() del runtime JS.
Lo más sencillo en estos casos es que insertes en la página una función JS que sea la que devuelva ese valor, algo más o menos así:
window.getScreen = function() {
return window.screen;
}
Y así, desde tu código Blazor podrías llamar sin problema a ese getScreen() para obtener lo que necesitas.
Saludos!
Enviar un nuevo comentario