I have a problem where I pass a local parameter of type Integer to another page via the "Destination" widget, for the page this parameter is defined of type "Entity" Identifier, in this case the entity is called Contract and the parameter expected is ContractId of type "Contract Identifier".
I stepped through the code, the local integer has value 9, but when I break in the "Preparation" of the page it is passed to, the value received for ContractId is zero.
I require this because of the following scenario I implemented:
I have a generic central Calendar where different tasks are entered from different tables, to achieve this I store in the Calendar the "source" entity and then a generic "RefrenceId" of type Integer which shall represent the ID of the record in that entity. When the user clicks on the calendar item it opens the associated "source" page/screen using a switch that switches over the "source" entity and passes the generic "ReferenceId" to that page, but the target page has a specific entity type id data type; for example the target page is the entity Contract then the ContractId is expected and this is of "Contract Identifier" type, or I have a target page KPI expecting and identifier of type "KPI Identifier".
So I need to use a generic "ReferenceId" of type integer.
I did fnd a work-around, what I do is I declare another local variable of the type of the target page (in the switch, before I call the target Destination), for example "Contract Identifier", and assign the "ReferencId" integer to this, then I pass this "ContractId" to the "Contract" page and then it retains the value of 9 and it reaches the page.
I would like to know what is the correct way of converting an integer to a defined Entity Identifier.
I also would like to know why the integer was converted to zero when it was passed directly to the ContractId of the page, and when I assigned it to a local variable of type "Contract Identifier" it does not make it zero?
I think you could do this with the old function IntegerToEntityRefInteger() or with the new one IntegerToIdentifier()
Carlos Conde wrote:
Thank you Carlos. I did not know about IntegerToIdentifier(), will remember, might come in handy in other cases. In this case however it still did not work. In other words where I pass the "ContractId" to the page I used IntegerToIdentifier("integer variable contract id") in the expression, but the page still received ContractId of 0 (zero) instead of 9. So for now I am going to always declare a local variable of the identifier type first, assign the integer and then pass this to the page, this is the only one that seems to work for now. Perhaps I should log a support call, maybe it is a bug?
can you share an simple example oml?
It should work, but perhaps there is something else fishy.
Is ContractId the first parameter of the page? If not, could you reorder it to the top (i.e. as the first parameter) and see if that works? There's some fishy bug in the Platform that sometimes causes the behaviour you wrote.
Thanks J. and Kilian.
@Kilian, this is my only parameter to the web screen.
@J. I created an oml sample and attach. A Calendar table with Contract (which I quickly scaffolded to make manual entry). The Calendar now has the "SourceId" identifier and the generic "ReferenceId" identifier which is an integer. The source is "Contract" so on the home page is the user's Calendar task box with the entry for the Contract, when the user clicks on the task it must, according to the source, open the correct page and pass the "ReferenceId" integer. This happend on the HomePage "OnOpenCalendarTask". So here I simply pass the Calendar table's "ReferenceId" integer, and in the ContractDetail page we get ContractId of 0 (zero).
So now add an assignment of the local Contract Identifier "ContractId" variable and assign the "ReferenceId" to this, which is:
SyntaxEditor Code Snippet
, then pass the local CotnractId variable to ContractDetail and it works. I tried to pass
but this still got me 0 in the ContractDetail web screen.
Silly question perhaps,
but are you sure referenceID is filled with a non-zero?
but are you sure ReferenceID is filled with a non-zero?
Yes, definitely, I break in the code and check and it has a value.
Another question: did you check what the value is in the screen URL? The parameter will be passed like ?ContractId=<value>, where <value> is the Id.
The debugger has a quirk where it optimises the values in the debugger window and it appears that the values are empty.
To double check that the identifier is being passed, add the input variable to an expression on the page in addition to Kilian's recommendation for the URL.
Reviewing your OML, the only item that I can see that maybe an issue is the IntegerToIdentifier cast.
Ouen Worth wrote:
Thanks Ouen for taking the time to look into this. I can confirm it reaches the page with a value of 0, I did add it to the page to display the value received in the parameter with an expression and it was 0, without running through the debugger. Also the Contract does not load, the page remains empty, so the ContractId is not found, it does not load the one with id 9 that was passed which definitely exists.
The URL also nothing can be seen there because it is an HTTP POST the parameters are in the body, (will dump and analyse the body later, not looked at that yet, is there an easy way in OutSystems to see the HTTP request body?), but I am almost sure it will show 0 is passed.
I do not think the IntegerToIdentifier() cast is an option. I did not use it in my example OML which I uploaded because I did try that and it also did not work, still passed 0.
But I think this is OK for me at the moment, thanks :), at least I found a work-around, declare a local variable of that Entity Identifier type that has to be passed to the web screen, and assign the integer value to this and then pass this. It seems there may be really an issue with this though, was wondering if I should log a call with OutSystems?
always log a call :)
Ok, did some debugging and I found the bug. It's yet another Integer vs. Long Integer bug. The problem is that Calendar.ReferenceId is an Integer, but Contract.Id is a Long Integer. IntegerToIdentifier() produces an Integer, not a Long Integer (which it should, given that the target is a Long Integer!), so the call fails (I'm not sure exactly why, but it does). Replacing IntegerToIdentifier() with LongIntegerToIdentifier() fixes the problem. I would consider this a bug however, so please report it to OutSystems (firstname.lastname@example.org) and also refer them to this thread (and in particular this answer).
In general, to avoid bugs like this, I'd always set Id to Integer instead of the default Long Integer to avoid these problems (assuming you're not creating a table with more than 2^31 entries).
Kilian Hekhuis wrote:
Thank you Kilian, that makes absolute sense. Also declares why it worked when I locally assigned it to the Contract Identifier (which is a Long int) then pass this. Still weird though that local assignment works, but not passing it to the web screen, I guess there must be some internal validation of types before it is passed to a web screen with different rules that causes this, one should be able to convert integer to long integer safely. I am new to OS, so I did not know one can fiddle with the ID type, but I think I will rather not (too green still), will opt for the solution I have currently. Then also I am thinking now it will work perhaps if I simply make my "ReferenceId" generic ID a Long Integer instead of an Integer? I am sure that will do it, I will test, but not have time right now, meetings, meetings.....
Yeah, that should it as well. As I said, it's just a bug in the Platform, which OS should fix (which I'm sure they will some time or other, if you report it).
Hi Kilian and Elize,
Thanks for spoting this. We added this bug to our team backlog and we'll try to fix it in the near future.
My apologies - only back from all the meetings, meetings.... now. Then I do not need log a call.