TL;DR
The WebPageViewer add-on has an overload to accept some JavaScript. You can use that to execute arbitrary script locally. WebPageViewer.SetContent(HTML: Text; JavaScript: Text);
JSON Formatting
This post starts with me wanting to format some JSON with line breaks for the user to read. It’s the response from an Azure Function which integrates with a local SQL server (interesting subject, maybe for another time). The result from SQL server is serialized into a (potentially very long) JSON string and this is the string that I want to present in a more human-readable format.
Sometimes I converge on a solution through a series of ideas, each of which slightly less bad than the previous. This was one of those times. If you don’t care about the train of thought then the solution I settled on was to use the JavaScript parameter of the WebPageViewer’s SetContent
method.
If you’re still here then here are the stations that the train of thought pulled into, starting with the worst.
Requirement
Have some control on my page for the user to view the JSON returned from the Azure Function, formatted with line breaks.
1. Format at Source
Why not just add the line breaks when I am serializing the results in the C# of my Azure Functions? That way I don’t need to change anything in AL.
No, that’s dumb. That would make every response from the function larger than it needs to be just for the rare occasions when a human might want to read it. Don’t do that.
2. Call an Azure Function to Format the Result
I could have a second Azure Function to accept the unformatted result and return the formatted version. I could have a Function App which runs node.js and return the result in a couple of lines of code.
Wait, that’s absurd. Call another Azure Function just to execute two lines of JavaScript? And store the Uri for that function somewhere? In a setup table? Hard-coded? In a key vault? Seems somewhat over-engineered.
3. Create a User Control
Hang on. I’m being thick. We can execute whatever JavaScript we want in a user control. I can create a control with a textarea, or just a div, create a function to accept the unformatted JSON, format it and set the content of the div. No need to send the JSON outside of BC.
Closer, and if you want more control over how the JSON looks on screen probably the best bet. But, is it really necessary to create a user control just to execute some JavaScript? Still seems like too much work for what is only a very simple problem.
4. Use WebPageViewer
The WebPageViewer has a SetContent
method (which I’ve written about before) which can accept HTML and JavaScript.
If you pass some script it will be executed when the page control is loaded. Perfect for what I need. I can just use the JSON.parse and JSON.stringify functions to read and then re-format my JSON text. I’m also wrapping it in pre
tags and removing any single quotes in the text to format (because they will screw the JavaScript and I can’t be bothered to handle them properly).
The AL code ends up looks like this:
local procedure SetResult(NewResult: Text)
var
JS: Text;
begin
NewResult := NewResult.Replace('''', '');
JS := StrSubstNo('document.write(''<pre>'' + JSON.stringify(JSON.parse(''%1''), '''', 2) + ''</pre>'');', NewResult);
CurrPage.ResultsCtrl.SetContent('', JS);
end;
If you’re not using 26 single quotes in three lines of code then you’re not doing it right
*This post is locked for comments