You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have some Async members in an object that I would like to render with RenderAsync.
For example:
vardata=new{ value = Task.FromResult(42)};
However, if I send this data to RenderAsync, value remains a Task<int> — it doesn't get awaited to its underlying value:
varresult=await Template.Parse("Hello {{ value }}").RenderAsync(data);
Console.WriteLine(result);// Output: Hello System.Threading.Tasks.Task`1[System.Int32]
Of course, it wouldn't make sense to await Tasks in Render, but for RenderAsync it would be useful to await any Task objects and display their result values (i.e., "Hello 42" in the above example)
Any thoughts on how to best accomplish this? Am I missing some configuration setting that enables this?
The text was updated successfully, but these errors were encountered:
Here's the approach I've come up with, but open to suggestions if there's a better approach
using System;using System.Threading.Tasks;using Scriban;using Scriban.Runtime;using Scriban.Syntax;namespaceScribanAsync{publicclassTemplateContextAsync:TemplateContext{publicoverrideasyncValueTask<object>EvaluateAsync(ScriptNodescriptNode,boolaliasReturnedFunction){// base implementationvarvalue=base.EvaluateAsync(scriptNode, aliasReturnedFunction);// is the object also a Task? If so, await its valueif((await value)is Task valueTask){// TODO: Is there an alternative to using dynamic?// TResult of Task<TResult> is unknown here.varresult=await(dynamic)valueTask;// return a ValueTask of the awaited valuereturnnewValueTask<object>(result);}// object is not a Task, just return the ValueTask<object> as usualreturnvalue;}}classProgram{staticasync Task Main(string[]args){vartemplate="Hello {{ a }} | {{ b }} | {{ c }}";vardata=new{
a ="World",
b = Task.FromResult(42),
c = Task.Run(async()=>{await Task.Delay(5000);return"Thanks for waiting";})};// Current approach// > Hello World | System.Threading.Tasks.Task`1[System.Int32] | System.Threading.Tasks.UnwrapPromise`1[System.String]varresult1=await Template.Parse(template).RenderAsync(data);
Console.WriteLine(result1);// New approach// > Hello World | 42 | Thanks for waitingvarscriptObject=new ScriptObject();
scriptObject.Import(data);varcontext=new TemplateContextAsync();
context.PushGlobal(scriptObject);varresult2=await Template.Parse(template).RenderAsync(context);
Console.WriteLine(result2);
context.PopGlobal();}}}
I have some Async members in an object that I would like to render with RenderAsync.
For example:
However, if I send this data to
RenderAsync
, value remains aTask<int>
— it doesn't get awaited to its underlying value:Of course, it wouldn't make sense to await Tasks in
Render
, but forRenderAsync
it would be useful to await any Task objects and display their result values (i.e., "Hello 42" in the above example)Any thoughts on how to best accomplish this? Am I missing some configuration setting that enables this?
The text was updated successfully, but these errors were encountered: