@TerraIndexService @nosweat
<<if [false]>> // code inbetween if-statement gets "evaluated"`
<<foreach [foo in bar]>><</foreach>> // results in an error (because of var-assignment)`
<</if>>
Actually, tags within a false-if branch are never evaluated, but are always parsed. And the error encountered is a parse-time error.
GroupDocs.Assembly supports a subset of C# language in its template syntax and mimics C# compiler behavior to some extent. For example, parsing of template syntax corresponds to compile time. Thus, parsing of a whole template happens all the time before evaluation of its very first expression.
Actually, this is not a bug. Here is a relevant quote from the DocumentAssemblyOptions.AllowMissingMembers reference:
Specifies that missing object members should be treated as null literals by the assembler.
So, when DocumentAssemblyOptions.DocumentAssemblyOptions
is applied, <<var [v = missingMember]>>
becomes <<var [v = null]>>
. In pure C#, on attempt to use a construction like var v = null
, a compile-time error appears, because the type of the variable cannot be determined. GroupDocs.Assembly is less restrictive and allows to proceed, but it cannot determine the type of a variable from a null literal as well, so it fallbacks to object
.
We cannot simply use, for example, IEnumerable
in this case. That said, there is a technical possibility for passing information about missing members further to variables initialized from them and we plan to proceed in this way, but it requires time.
Thanks for your response!
That said, there is a technical possibility for passing information about missing members further to variables initialized from them and we plan to proceed in this way, but it requires time.
Do you mean that you are working on this improvement? Any timeframe available?
A way to make this work would be a life-saver for us:
using Options = DocumentAssemblyOptions.AllowMissingMembers
;
<<var [bar = data.propertyThatMayOrMayNotExist.Collection]>> // real statements used are far more complex and need to be split up
<<foreach [foo in bar]>><</foreach>> // results in "Can not iterate over an instance of type System.Object"
@nosweat
We cannot share any ETA at the moment (we’ll notify you as soon as we have the ETA).
Hi, then this is still a Bug, because in that case it should not complain about iterating a System.object. Then is should be able to use the null check, and not throwing a parse error. But there is no single null check avaible once you go into a foreach or when you try to get an extra filter or function on a null variable.
- The foreach should check the null
- and the bar?.Where() should not throw an parse error
@TerraIndexService
We’ll continue our investigation and will notify you in case of any progress update.
@TerraIndexService
Here are further details from a technical perspective.
As a workaround, to avoid repeating of complex expressions in templates, you may consider transformation of your data being passed to DocumentAssembler
.
As explained earlier, when DocumentAssemblyOptions.DocumentAssemblyOptions
is applied, <<var [v = missingMember]>>
becomes <<var [v = null]>>
. If a statement like var v = null; foreach (var i in v) { }
in pure C# is compiled, then a compile-time error regarding its first step (that is, var v = null;
) appears. So overall, the scenario does not work.
When corresponding template syntax is used, GroupDocs.Assembly does not raise an error on the first step, but raises an error on the second one. So overall, the scenario does not work either, the same way as for pure C#.
The main technical reason for this is that C# does not have a type for a null literal, so both a C# compiler and GroupDocs.Assembly do not support the scenario, but report about the error at different times, which may be confusing.
However, we do understand inconveniences that you face, so we plan to work on support of the scenario (which is technically possible). But we cannot share any ETA.
1 Like
Thank you for your understanding.
We are looking forward to hearing from you.
Any news, or any known workaround available at the moment?
Thanks.
@nosweat
No updates or changes have occurred regarding the ticket at this time. We apologize for any inconvenience caused. For more information, including any available workarounds, please refer to our previous comment. Thank you for your understanding.
Hi Atir,
do you now have any update?
Because the workaround is not workable for us, and we are having some projects being blocked by this issue.
@TerraIndexService
If the suggested workaround is not suitable, you can try resolving the issue by simply copying and pasting the template expressions. We apologize for any inconvenience caused.
Is there any way to get this issue solved, it is one of our 2 issues what is blocking us from deploying the new reporting to production. We have many customers waiting for this feature, and our complete investment is hanging on this issue. So is there any way, maybe financial, maybe source code?
@TerraIndexService
We kindly request your patience as we conduct further investigations.
From a technical perspective:
Not being able to null-check a var means any conditional expression will break when data is missing.
Think of conditional formatting, filtering, and also inner-foreach.
Transforming the input is not an option, because that would mean to completely flatten the data structure. This would no longer allow us to create many rich reports from a single dataset, which is the greatest strength of GroupDocs in our opinion.
This statement would fail in C#, as var
requires an underlaying type;
var test = null
Perhaps in GroupDocs the type can become object
or pref. dynamic
, which can be null-checked;
var test = (dynamic)null
I guess we should then be able to do something like this;
var test = data?.collection ?? new List<dynamic>()
foreach (foo in test) { }
@nosweat @TerraIndexService
To expedite the resolution of your issue, you have the option to opt for priority/paid support. This will ensure dedicated attention and faster assistance.
please, what would the price be to fix this issue?
We’re still thinking about the option. some more insight in the issue:
The problem occurs when attempting to iterate over an assigned variable within an empty array.
Say that I have the following data:
{“MeasurementObject”: [
“filterTubes”: [],
]}
And this filterTubes array can be filled with another array - but at the moment of creating the report, I cannot know whether or not this data is filled. The following statement will work:
<<foreach [filter in MeasurementObject.FirstOrDefault().filterTubes]>><<foreach [item in filter?.filterArrays]>><<[item.name]>><><>
But this one won’t:
<<foreach [filter in MeasurementObject.FirstOrDefault().filterTubes]>>
<<var [filterArrays= filter?.filterArray]>>
<<foreach [item in filterArrays]>><<[item.name]>><><>
If we had to option to assign an typed array object (var array [] {}) or something like var = [a = b ?? new [] ] we could work with this, but this doesn’t seem to work. We need to be able to assign certain variables in deeply nested arrays.
Btw Paid Support won’t give any guarantees that this issue will be handled, or even that they will look at it. Isn’t there anyway to back this issue up, with some financial boost? That it will be fixed within 2 months ?