Announcement

Collapse
No announcement yet.

What is this MvWHILE conditional doing?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    What is this MvWHILE conditional doing?

    Hi all, I'm trying to figure out how to handle looping through an MvOPENVIEW result set and have a question about the best way to do it. I've been using Tess Guefen's Waitlist module for information about how to set up my module, but had a question when it came to how her MvWHILE loop was set up.

    Here's a link to the .mv file on github: https://github.com/tessguefen/Waitli.../TGWaitlist.mv

    and here's an MvWHILE loop to consider:

    HTML Code:
    <MvFUNCTION NAME = "Waitlist_Trigger_EmailsXProduct" PARAMETERS = "product_id, variant_id" STANDARDOUTPUTLEVEL = ""  ERROROUTPUTLEVEL = "">
        <MvIF EXPR = "{ NOT Waitlist_Product_Check( l.product_id, l.variant_id, l.waitlist) }">
            <MvFUNCTIONRETURN VALUE = 0 />
        </MvIF>
    
        <MvOPENVIEW NAME    = "Merchant"
                    VIEW     = "TGWaitlist"
                    QUERY     = "{ 'SELECT * FROM ' $ g.Store_Table_Prefix $ 'TGWaitlist WHERE product_id = ? AND variant_id = ?' }"
                    FIELDS    = "l.waitlist:product_id, l.waitlist:variant_id">
    
        <MvIF EXPR = "{ g.MvOPENVIEW_Error }">
            <MvFUNCTIONRETURN VALUE = "{ [ g.Module_Library_Utilities ].Error( 'TGWaitlist-CHECK-1003:', 'An error occured while checking a record.' ) }">
        </MvIF>
    
        <MvASSIGN NAME = "g.WaitlistCount" VALUE = "0">
    
        <MvWHILE EXPR = "{ ( NOT TGWaitlist.d.EOF ) AND ( ( g.WaitlistCount EQ 0 ) OR (l.waitlist_num LT ( g.WaitlistCount + 1) ) ) }">
            <MvEVAL EXPR = "{ Waitlist_Read( l.waitlist ) }">
            <MvDO FILE = "{ g.Module_Library_Utilities }" NAME = "l.waitlist:formatted_date" VALUE = "{ Format_Date( l.waitlist:time_added, s.miva_language ) }">
            <MvASSIGN NAME = "l.success" VALUE = "{ Waitlist_Trigger_Email_Lowlevel( l.waitlist ) }">
            <MvASSIGN NAME = "l.waitlist_num"    VALUE = "{ l.waitlist_num + 1 }">
    
            <MvSKIP NAME = "Merchant" VIEW = "TGWaitlist" ROWS = 1>
        </MvWHILE>
    
        <MvCLOSEVIEW NAME = "Merchant" VIEW = "TGWaitlist">
    
        <MvFUNCTIONRETURN VALUE = 1>
    </MvFUNCTION>
    As you can see, the MvWHILE loop is based on two counters plus the EOF row.

    I couldn't quite wrap my head around what's going on above or what the counters were doing, so I looked in the LSK and found an example where the MvWHILE condition was based just on the EOF row, i.e. (as an example, using the same view name as above)

    HTML Code:
    <MvWHILE EXPR = "{ NOT TGWaitlist.d.EOF }">
         ...
    </MvWHILE>
    What's the best practice when it comes to looping over a result set from MvOPENVIEW? And what is the module doing if simply checking for the EOF row is sufficient for the MvWHILE loop? Thanks for any info!

    Edit: Also, while I have you here (>:)), is it possible to have nested <MvOPENVIEW> tags? I assume no, but would be interested to know for sure!
    Last edited by new_user2018; 08-10-18, 11:58 AM.

    #2
    Ok,
    So here is my take (although I am sure there will be others)...
    1 - Best way is the simplest. <MvWhile expr="{ NOT dbase.d.EOF }">
    2 - if needed, add conditionals ... <MvIf expr="{ table.d.somefield EQ 'xxx'> do something... <MvWhilestop></MvIf>
    3 - If cycling thru a table, be sure to <MvSkip name="dbasename" view="viewName">

    And yes - you can have nested MvWhiles.... I do this alot.... ie - loop thru a table to locate a specific name, then use that name to loop thru another to find an option... then stop the loop and return to the first one. Repeat.

    Here is an awesome resource. http://www.mivascript.com/item/mivas...s/MvWHILE.html
    William Gilligan - Orange Marmalade, Inc.
    www.OrangeMarmaladeinc.com

    Comment


      #3
      To add to William's comments:

      It's better to make a database call that limits the records returned rather than discarding ones you don't need. (Not sure what TG was doing here, so there might be other reasons to externally limit the records.)

      I.e.,
      Code:
       
       SELECT * FROM table WHERE id = ? LIMIT 5
      Originally posted by wmgilligan View Post
      Ok,

      And yes - you can have nested MvWhiles.... I do this alot.... ie - loop thru a table to locate a specific name, then use that name to loop thru another to find an option... then stop the loop and return to the first one. Repeat.
      Were is an awesome resource. http://www.mivascript.com/item/mivas...s/MvWHILE.html
      I think OP was asking about Nested Openviews. The answer is 'depends'. If you mean opening the same DB, you'd have use another alias or close the initial view. If you mean another DB, sure...but watch the opens and closes. In this case, I'd make the Openview for each DB a separate function just for sanity.
      Bruce Golub
      Phosphor Media - "Your Success is our Business"

      Improve Your Customer Service | Get MORE Customers | Edit CSS/Javascript/HTML Easily | Make Your Site Faster | Get Indexed by Google | Free Modules | Follow Us on Facebook
      phosphormedia.com

      Comment


        #4
        Thanks for the help, both of you! This is my first time creating a module and it's been a real head scratcher as to why my scheduled task is logged as starting but never stopping. I figure it's something to do with my MvWHILE loops, as when I placed an explicit counter to stop on the 5th row of the query result the task stopped correctly.

        When I was reading through your list of things to do, I got to #3 about the MvSKIP and was like 'Duh, I wouldn't forget that...', and lo and behold, I forgot to include an MvSKIP tag. Doh!

        I wish I knew of some better tools to help while writing this module though... hell I don't even know where I can log messages and what not to show that I got to this step or that step of the module for debugging things.

        Comment


          #5
          The most consistent (meaning it works in almost all places), is to output a 'log' file using MvExport. In fact, I have <mvexport file="debug.dat" fields="thisValue,thatValue" delimiter="|"> in my Syntax clip library.

          Then I have that file auto downloaded via FTP or editor. A bit of a PIA, but saves boat loads of time
          Bruce Golub
          Phosphor Media - "Your Success is our Business"

          Improve Your Customer Service | Get MORE Customers | Edit CSS/Javascript/HTML Easily | Make Your Site Faster | Get Indexed by Google | Free Modules | Follow Us on Facebook
          phosphormedia.com

          Comment


            #6
            That will be incredibly helpful to have, thanks Bruce!

            Comment

            Working...
            X