FoxInCloud
Error when drawing a grid
Gravatar is a globally recognized avatar based on your email address. Error when drawing a grid
  Paul
  All
  Jan 16, 2019 @ 03:28am

Hi,

I have a form with an "empty" grid in it (no recordsource or columns) and at runtime I programatically configure the grid - set the recordsource, add the columns etc etc.

The code that does this works correctly, but after the code exits and it is being turned into HTML I receive this error :

Form stockcontrolcheckarea : AWAJAX.CRESULTADD - awajax.lSuccess(.f.): Error detected at code line #15,193 of method 'awajax.propchangedhtml_grid'
"Method or procedure gethtml_grd_aw_cscript_events_cols(): error #1924 ("COLUMNS is not an object") at code line #12,856 (source code N/A)"
FoxInCloud Application Server will attempt to re-instantiate form 'stockcontrolcheckarea' and retry the user request.

I see that awgrd has a wlContentDynamic property, but not a wlContentChanged property; I set wlContentDynamic = .T., but the error still occurs so I don't know if I need to do that or not.

Any ideas?

Thanks Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Vincent H.
  Paul
  Jan 16, 2019 @ 10:23am

Hi Paul,

Forgot a dodefaut () ?

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 16, 2019 @ 01:49pm

Because digging into the grid members is faster than regenerating HTML for a container's members, we've omitted .wlContentChanged

To my knowledge, this error happens only when use in (.recordSource) without prior setting .recordSource = ''.

If that helps, you have a sample form using .wlContentDynamic: MODIFY FORM home(1) + "tools\ab\aw\samples\fic\fictuto\progs\forms\dataupdate.scx"

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Jan 24, 2019 @ 08:09pm

The answer was to put some code in the this.wlInitFirst section of the form's Init() :
...use the view nodata
Grid.wlContentDynamic = .T. Grid.RecordSource = "alias of the view"
...configure the grid and its columns

It is not enough to have that code executed later in response to a user event, it appears that the columns must be defined during wlinitFirst.

Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 25, 2019 @ 01:31am

Thanks for the follow up; we'll try to reproduce and find a workaround

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Jan 30, 2019 @ 02:29pm

Actually I was wrong, my code change did not fix the problem (I was accidentally not creating any columns).

So I have gone back to the original code pattern, where the grid is initially unconfigured (.recordsource = "") and I only set things up in the user event.

I am still trying different things to make this work, but in the meantime here are some things I have noticed :

  • I can see 2 instances of the form being created by FiC when I navigate to the form - is this normal?
    At the moment I am calling the form by :
  1. logging in using a login form
  2. displaying a menu form
  3. navigating to index.htm and running my form from there, as the menu form isn't working yet
  4. note that form.wlPrivate = .F.
  • In the user event (textbox.Valid) I set up the grid. When I add a column via grid.AddObject() it runs the FiC code and it crashes because I have grid.wlContentDynamic = .T.
    This is the FiC code :
if lProperty(m.this, 'wlContentDynamic') and m.this.wlContentDynamic   && Si wlContentDynamic, tout le HTML contenu est régénéré à chaque requête  
this.wlContentChanged = .T.  
...

The problem is that a grid does not have a wlContentChanged property.

.

Incidentally, I have observed another strange problem while testing that form.
In the Load of the form I open view A and in the Init of the form, inside the wlInitFirst section, I open view B.
FiC has created 2 instances when the form is requested, as I mentioned above, with DataSessionID's of 16 and 18 - I'll refer to them as 16 and 18.
I see the Load of 16 and 18 executed once each - view A is open in each
I see the Init of 16 executed once, with wlInitFirst = .T. - views A & B are now open in 16
I see the Init of 18 executed once, with wlInitFirst = .T. - views A & B are now open in 18 and when I look at 16 I see that view B is no longer open in that datasession!!
I see the Init of 16 executed again, with wlInitFirst = .F. - view A is open and view B is not
Looking at 18, views A & B are open

Wow, really confused. Sure, I could open each view in the Load and requery later on (they are parameterised), but ... do I have to?

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  Paul
  Jan 30, 2019 @ 08:50pm

I notice in your FiCTuto example, the columns are defined in the Init of the grid and the grid.recordsource and column.controlsource is not set until the Init of the form, after the this.wlInitFirst section.

Is this the timing that must occur for a grid that is built at runtime?
Do the columns have to be defined prior to the form's Init?
When is the HTML for a (.wlContentDynamic = .T.) grid and its columns actually generated?

Thanks
Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 31, 2019 @ 01:50am

I could open each view in the Load and requery later on (they are parameterised), but ... do I have to?

Definitely YES; All views and CAD must be USEd before calling dodefault() in form.load()
(notice the name of the fake parameter to this method inherited from awFrm.Load(): reminder_in_your_subclass_call_DoDefault_after_opening_all_views_and_cursorAdapters -- generally speaking, please take some time to review the aw*.method code when implemented, it often contains useful documentation).

Here is the call stack:

yourForm.Load()
yourFormClass.Load()
awForm.Load()
  …
  this.AddObject('wColView', m.this.wColViewClass) && by default awColView of aw.vcx
awColView.Init()
  this.wSaveAll(@m.result)
    this.wSave() && stores a view definition object as a member of the collection

FoxInCloud automatically closes views that were not identified at awForm.Load():

procedure awColView.wRestoreAll

…
for iView = 1 to m.nView && unused views
	cView = m.aView[m.iView]
	success = !wlAppHost(@m.oAppHost) or m.oAppHost.AliasRecordSourceClear(thisForm.DataSessionID, m.cView) && always returns .T.
	use in (m.cView) && here it is…
endfor

This behavior explains this:

when I look at 16 I see that view B is no longer open in that datasession!!

Not sure why we implemented that back in 2015, probably after a thorough analysis… we could add a property to work around this behavior, however it could only be applied to non-parameterized views as views need be registered in .wColView to get an automatic requery() when restoring datasession for the user.

Only one rule: USE view NODATA in dataEnvironment or form.Load(), call dodefault(), .wViewParmSet() in form.Init() after the this.wlInitFirst section, and/or in any user event method, and/or .Refresh_().

This obeys the standard VFP coding pattern where all data are made available before member objects get instantiated to let them set their .*Source on the USEd data.

FiC has created 2 instances when the form is requested

Not sure why… maybe you could post the content of the goWCserver.oAppHost.aForms array like illustrated here (from the debugger locals window):

The problem is that a grid does not have a wlContentChanged property

Typo on our side because we generate the code of all classes having .wlContentDynamic using the same method; maybe you could:

modify class awGrd of aw method addObject

&& replace
this.wlContentChanged = .T.

&& by
this.addProperty('wlContentChanged', .T.)

Is this the timing that must occur for a grid that is built at runtime? Do the columns have to be defined prior to the form's Init?

Not intended so…

We paid more attention to your original post and noticed the error occurs during a user event, while refreshing the grid, as opposed to initial HTML/CSS/JS generation:

Error detected at code line #15,193 of method 'awajax.propchangedhtml_grid'
awajax.*() run only in response to a user event, or form.Init().

Looking at the code in Method gethtml_grd_aw_cscript_events_cols() where error occurs, there is a mismatch between .columnCount and actual .columns.count. This happens generally when closing (.recordSource) without prior .recordSource='': VFP destroys the columns without changing .columnCount

Just a trail to look into, not exactly sure.

At some point you may need the full version (with source code) to run in debug mode and be able to see all the variables and properties when error occurs.

When is the HTML for a (.wlContentDynamic = .T.) grid and its columns actually generated?

Initially, at .wlInitFirst, and upon each user request in case of a change.

If grid.wlContentDynamic, as it's difficult and maybe impossible to update the structure of the ActiveWidget grid, FoxInCloud compares the XML describing the grid before / after the event (stored in a record labeled GRIDRS in the form state table) and, in case of any structural change, re-generates everything (actually JavaScript as ActiveWidget only works in JS).

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Feb 1, 2019 @ 08:35am

Next week we’ll create a ‘dynamic grid’ sample in FoxinCloud Live Tutorial.

Hopefully you’ll find in it answers to your issues.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Feb 10, 2019 @ 06:16pm

FiC creates 2 instances of the form stockcontrolcheckarea.
stockcontrolcheckarea has this class hierarchy :
form, awfrm, sficfrm, standardfrom, privatedataform, mfgprivatedataform, shopfloorbaseform, stockcontrolbaseform, stockcontrolcheckarea Instance 1

Instance 2

After instance 2, here is _screen.forms (note the duplicates) :
Note that it appears that maybe the first instance of stockcontrolcheckarea was created before the instance of its parent class, stockcontrolbaseform, just looking at the order of the forms here.

And yet, stockcontrolcheckarea only occurs once in the aforms array :

Still playing with the grid, trying to make it work.
So far I can confirm that by the time my grid initialisation code finishes, the grid contains 8 columns and grid.ColumnCount = 8.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Feb 10, 2019 @ 11:54pm

Hi Paul,

Yes, FoxInCloud instantiates each class during the HTML generation process, to assign the CSS properties to the right class level (see awDefault*.css).

There might be another way using pemStatus() however we could not make it work so far.

Late on the 'dynamic grid' sample, we'll work on that this week.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Mar 27, 2019 @ 08:50pm

Hi,

I have looked at your dynamic grid sample and cannot really see the difference between how that works and what our dynamic grid does; although our system is a lot more complicated, at its heart it basically goes through the same steps to add columns.

I don't have the FiC source code, but I have narrowed down what is going wrong :

  1. form.load opens the cursor and the grid has its recordsource set to this alias at design-time; grid.ColumnCount = 0
  2. from a user event, code runs to generate the columns, set the controlsource etc - all good
  1. grid.ColumnCount = 8 and the grid contains 8 columns objects, Column1...Column8
  1. FiC tries to generate the HTML
  1. I have a breakpoint on when Column1 disappears, it triggers...
  2. grid.ColumnCount = 8, but the grid now only contains only 1 column object - Column8
    (I notice there is now a property named grid.odynamiccolumn0; presumably FiC has created this, named after the class of the columns?)
  3. --what happened to Column1...Column7 ?
  4. I resume...
  5. crashes with "Columns is not an object"

Here is the stack trace :

#21 awhtmlgen.gethtml_grd_aw_cxml_rs_, awhtml.fxp, Line 9536
#20 awhtmlgen.gethtml_grd_aw_cxml_rs, awhtml.fxp, Line 9211
#19 awhtmlgen.gethtml_grd_aw_cxml_, awhtml.fxp, Line 8972
#18 awhtmlgen.gethtml_grd_aw_cxml, awhtml.fxp, Line 8891
#17 awajax.propsave_cpv_grid, awserver.fxp, Line 12084
#16 awajax.propssave_user, awserver.fxp, Line 11001
#15 awajax.propssave, awserver.fxp, Line 9744
#14 awajax.xmlpropschangedadd, awserver.fxp, Line 16052
#13 awajax.formrequestcomplete, awserver.fxp, Line 9355
#12 awajax.formrequest, awserver.fxp, Line 9317
#11 sficprocess.ajaxformrequest, awserver.fxp, Line 4648
#10 sficprocess.domevent, awserver.fxp, Line 4632
#9 wwprocess.process, wwprocess.fxp, Line 272
#8 sficprocess.process, awserver.fxp, Line 2733
#7 sfictestserver.routerequest, awserver.fxp, Line 928
#6 sfictestserver.process, awserver.fxp, Line 909
#5 sfictestserver.processhit, wwserver.fxp, Line 561
#4 sfictestserver.tmrfiletimer.timer, wcvisual.vct, Line 39
#3 awstart, awstart.fxp, Line 105
#2 awserverstart, awstart.fxp, Line 142
#1 sfictest, sfictest.fxp, Line 36

Hopefully this might identify what is happening...

Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Mar 27, 2019 @ 10:16pm

Hi Paul,

I have a breakpoint on when Column1 disappears, it triggers…

In which method does this breakpoint trigger? Could you post the stack?

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Mar 28, 2019 @ 01:10pm

The stack trace shown previously is when Column1 disappears.

Thanks
Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  Paul
  Mar 28, 2019 @ 10:00pm

I am running V 2.28.1-beta.3.

Well...I do not understand.
I made some changes to our grid system, they seemed not to make any difference...but now a few hours later the grid is no longer crashing with the "columns is not an object" error.
Instead, I see an empty grid (just the border and a scrollbar).

Looking a bit deeper, it is probably because the cursor that is the recordsource is being closed by FiC!!

Following your code pattern, I have a remote view opened in form.Load() (with nodata) before the dodefault(). But during debugging I can see that the cursor is no longer open by the time the form.Init() is executed, even the first time through.
As an experiment I opened another view in form.Load(), this time using the same alias as the name of the actual view - voila, this cursor remains open!
I also open another view in form.Load() with the same alias as the view name - that also remains open.

So - from my current testing it looks like there is a problem in FiC where a view that is opened with an alias that is different from the view name gets closed before form.Init().

I do not remember having this problem when I was looking into all of this a month ago, so perhaps beta.3 has a problem.

Also, I still don't understand why each of my forms is being opened in two instances, as I mentioned in an earlier post in this thread. I suppose I don't mind if that is what FiC needs to do to get class information - but it will execute form.Load() twice and open the data from that method twice, which is problematic from a performance angle.
Is this normal behaviour or only something that I am experiencing? Any ideas about the reason?

Thanks
Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Mar 29, 2019 @ 07:27am

Thanks Paul for these additional details

By design, and before any possible bug, FoxInCloud keeps cursors open, and re-creates them if another user has closed it. FoxInCloud also makes sure to clear any .rowSource and/or .recordSource set on the cursor before re-creating it (when needed).

This requires a lot of attention, which should be possible middle of next week.

Can you confirm all your forms use a private dataSession?

Have a nice week-end!

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Mar 31, 2019 @ 01:57pm

Yes, private datasessions.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Apr 3, 2019 @ 08:13am

a view that is opened with an alias that is different from the view name gets closed before form.Init()

aw.vcx!awColView handles this situation… you can check the form state table, browse for oa = "wcolview", modify memo PV you can see sourceName as an attribute, and

modi class awColView of aw method wRestore
…
use (m.oProp.database + '!' + m.oProp.SourceName) in 0 nodata alias (m.cView)
&& makes the difference between SourceName and alias

maybe you can debug this way:

modi class awColView of aw method wRestore
…
setstepon(m.cView = 'alias of your view') && add this line
use in (m.cView)

modi class awColView of aw method wRestoreAll
…
setstepon(m.cView = 'alias of your view') && add this line
use in (m.cView)

Please feedback if any of these set step on trigger

We may need private support to elucidate this issue.

Also, I still don't understand why each of my forms is being opened in two instances

explained here

we might consider working on using getPEM() instead with a sponsor

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Apr 4, 2019 @ 03:34am

I haven't tried your suggestions, but I did apply the code-fix you released the other day for beta.4 and since then I haven't had the problem with the view being closed by FiC.
I'm not sure I did anything else to fix it.

© 1996-2019