Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Dynamic Array Names

New Here ,
Jul 11, 2011 Jul 11, 2011

That's fairly complex to explain, so forgive me if I miss some details.

I got a code working for Coldfusion 9, but my host only uses Coldfusion 8, and I'm not in any position to change that (or to change host for that matter).

Now, I've a recipe list, users are able to choose one or several of the recipes and can add it to the "Grocery List", said grocery list is generated from the ingredients of the recipe. It starts out as any "shopping cart" application out there, however following the various tutorials on the subjet I always get stuck in getting the "Ingredients list", these tutorials allow to pass one variable, and hardly anything else.

Furthermore that list may be printed or downloaded via .txt file (to put on my phone), so I need to keep the data.

As explained above whatever I came up with does not work under CF8, so far I modified my code for what follows (note, I know that the "Evalute()" does not receive much love, so I tried to remove them, the ones I left are only because no matter what else I tried it did not work) :

<cfoutput>
    <!--- Loop through the first array containing the name of the recipees (that Array is called "ArList") --->
        <cfloop from="1" to="#arraylen(arList)#" index="counter">


            <!--- calling the Array via a method --->

               #arList[counter].Nom.getNom()#</th>
            
    <!--- Check if there is any array containing the Ingredient or if it is empty (just a security to avoid some bugs I encountered). If not, creates the array, each recipe gets his own ingredients based array, this way it is possible to erase unnecessary ingredient from the grocery list--->       
            <cfif not isdefined ("session.I_#counter#") OR ArrayIsEmpty (Evaluate("session.I_#counter#")) >

  <!--- A bit weird to launch the <cfinvoke> here, but it works, the query only returns the ingredients of the recipe at each loop --->
                <cfinvoke component="cfc.manoire" method="Display_Ingrid" returnvariable="Display_Ingrid">
                    <cfinvokeargument name="M_ID" value="#arList[counter].Nom.getM_id()#">
                </cfinvoke>

    <!--- Initialise the ingredient Array, these are dynamic since I can't predict how many recipees users will choose --->
                <cfset VARIABLES["session.I_" & counter] = ArrayNew(1)>
                
    <!--- Loop through the query to populate the Array --->           
                <cfloop query="Display_ingrid">
                    <cfset Arrayappend(VARIABLES["session.I_" & counter], structnew())>
                    <cfset position=arraylen(VARIABLES["session.I_" & counter])>
                    <cfset VARIABLES["session.I_" & counter][position].I_Nom = #I_Nom#>
                    <cfset VARIABLES["session.I_" & counter][position].Quantite = #Quantite#>
                    <cfset VARIABLES["session.I_" & counter][position].Unite = #Unite#>
                </cfloop>
            </cfif>


     <!--- Displaty the Arrays containing the ingredients' list, holds the hyperlink for the delete option. --->
            <cfloop from="1" to="#Arraylen(Evaluate('session.I_#counter#'))#" index="val">
                #VARIABLES["session.I_" & counter][val].I_Nom#
                #VARIABLES["session.I_" & counter][val].Quantite#
               #VARIABLES ["session.I_" & counter][val].Unite#
            </cfloop>

          </cfloop>
    </cfoutput>

I get a" Element session.I_1 is undefined in a Java object of type class coldfusion.runtime.VariableScope" at the beginning of the last loop.

I've tried with evaluate() and it has a problem starting [val], that's not something I found to be fairly well documented so I guess there must be something fairly simple and straightforward that completely escaped me.

I'm not set in any direction, so any advice and/or constructive criticism is/are welcome.

Thanks

1.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jul 11, 2011 Jul 11, 2011

It looks to me like it the combination of using evaluate() in the CFLOOP might be leading to CF looking for a variable variables.session.i_1.  if this is the case, then it's a CF bug, but you can get help yourself out by getting rid of the evaluate().  You never need to use evaluate() to access a variable name.

Just use:

session["i_#count#"], eg:

<cfloop from="1" to="#Arraylen(session['i_#counter#'])#" index="val">

--

Adam

Translate
LEGEND ,
Jul 11, 2011 Jul 11, 2011

It looks to me like it the combination of using evaluate() in the CFLOOP might be leading to CF looking for a variable variables.session.i_1.  if this is the case, then it's a CF bug, but you can get help yourself out by getting rid of the evaluate().  You never need to use evaluate() to access a variable name.

Just use:

session["i_#count#"], eg:

<cfloop from="1" to="#Arraylen(session['i_#counter#'])#" index="val">

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jul 11, 2011 Jul 11, 2011

I don't have a means to test any of this right now ( i am on vacation), but I thought I would take a moment to point out that an easier, and cleaner way to access the variables in the session scope dynamically is:

<cfset session["I_#counter#"][position].I_nom = "" />

Same with your ArrayIsEmpty() statement.

ArrayIsEmpty (session["I_#counter#"])

Could you indicate which of the above lines is actually erroring?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 11, 2011 Jul 11, 2011

Your logic problem is here.

<cfif not isdefined ("session.I_#counter#") OR ArrayIsEmpty (Evaluate("session.I_#counter#")) >

do stuff to populate the array.

Take away the or array is empty part to make it clearer.

By the way, as Adam said, you don't need to use evaluate.  Instead, use

ArrayIsEmpty(session["l" & counter])

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 11, 2011 Jul 11, 2011

Thanks to everyone.

The "session[I_#counter#]" you all indicated works very well, I had not encountered this one (or probably did not recognized it when I did).

Everything works fine now.

Thanks again.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 12, 2011 Jul 12, 2011
LATEST

The "session[I_#counter#]" you all indicated works very well, I had not encountered this one (or probably did not recognized it when I did).

The online docs are great...

http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09f0b-7fe9.html.  The specifics of associative array notation are on the second page, with a link through to more complex examples.  It might be worth having a read through it all.

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources