2

Can anyone see what is wrong with this loop? I am not a coldfusion developer but I am doing something for our absent developer. I am trying to get the loop to stop after 10 iterations but it is not happening. The CMS I am using is Mura. Thanks.

                    <cfset limit = 1>
                    <cfloop condition="iterator.hasNext()">
                        <cfif limit LTE 10>
                        <cfoutput>
                            <cfset item = iterator.next()>
                                <tr>
                                    <td>#item.getId()#</td>
                                    <td>#item.getTitle()#</td>
                                </tr>
                         </cfoutput>    
                         </cfif>
                        <cfset limit = limit + 1>
                    </cfloop>
Mike
  • 140
  • 8

3 Answers3

8

While Ben's answer will work, the best option is to tell the Mura iterator how many iterations to do before beginning the loop.

<cfset iterator.setNextN(10) />
<cfloop condition="iterator.hasNext()">
    <cfset item = iterator.next()>
        <cfoutput>
            <tr>
                <td>#item.getId()#</td>
                <td>#item.getTitle()#</td>
            </tr>
        </cfoutput>    
</cfloop>

Typically it defaults to 10, so somewhere in your settings or code it must be set to more.

Jason Dean
  • 9,585
  • 27
  • 36
  • That might not be a good option if more iterations are expected further down in the code! – David Faber Sep 06 '12 at 12:27
  • Actually, if you iterate again it will grab the next N items. So it's perfect for just that. – Jason Dean Sep 06 '12 at 12:50
  • No, I mean if you tell the iterator to do 10 iterations before beginning the loop, then the iterator will expect to do 10 iterations from then on, correct? And that might mess something up further down. I like your answer (it's very clean) but I just wanted to point out a possible issue if more than 10 iterations are needed/expected further below based on whatever value was already set. – David Faber Sep 06 '12 at 12:56
  • You can change the number of iterations at any point, you can also reset the iterator to start over again. So it is still the best solution all around. – Jason Dean Sep 06 '12 at 12:59
  • Yes, you can change the # of iterations at any point but what if a developer simply wants to make a small change and hasn't combed carefully through the code to see the initial settings? That's the only thing I am concerned about. – David Faber Sep 06 '12 at 13:00
  • 2
    Then the developer needs to get better at what he or she does. Because using the API correctly is what should happen. There is no justifying using twice the code to make things simple. There is nothing not simple about using or modifying my example. – Jason Dean Sep 06 '12 at 13:30
  • As the OP mentioned, he isn't a CF developer and is pinch-hitting for someone who is. I think it is fair to expect that such a developer should not mess with settings, but should leave them alone. – David Faber Sep 06 '12 at 20:14
  • It's not a setting, it's a line of code. It doesn't make any permanent or wide-spread changes. It changes the nextN for that instance of that iterator. – Jason Dean Sep 06 '12 at 20:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16388/discussion-between-jason-dean-and-david-faber) – Jason Dean Sep 06 '12 at 20:29
3

I would just check for limit GTE 10 and use CFBREAK to terminate the loop early.

<cfset limit = 0>
<cfloop condition="iterator.hasNext()">
    <cfoutput>
        <cfset item = iterator.next()>
            <tr>
                <td>#item.getId()#</td>
                <td>#item.getTitle()#</td>
            </tr>
     </cfoutput>    
    <cfset limit++>
    <cfif limit GTE 10>
        <cfbreak>
    </cfif>
</cfloop>
BKK
  • 2,073
  • 14
  • 17
  • Just as a note, the code above will iterate 11 times as limit starts at zero rather than 1 as in the original code. – David Faber Sep 06 '12 at 12:29
  • @DavidFaber I believe you are mistaken. On the 10th iteration limit will equal 10 and the loop will break – Jason Dean Sep 06 '12 at 17:47
0

There's also another option with <cfloop>:

<cfloop from="1" to="10" index="ii">
    <cfif iterator.hasNext()>
        <cfset item = iterator.next() />
        <cfoutput>
            <tr>
                <td>#item.getId()#</td>
                <td>#item.getTitle()#</td>
            </tr>
        </cfoutput>
    <cfelse>
        <cfbreak />
    </cfif>
</cfloop>
David Faber
  • 12,277
  • 2
  • 29
  • 40
  • I voted this down. What's the point of using an iterator if you are going to iterate yourself? Also, this method will loop X number of times no matter how many items are in the iterator. – Jason Dean Sep 06 '12 at 18:01
  • I don't see the distinction between using `` with an iterator (but stopping if it reaches a certain condition) and using with a while condition (but stopping at a certain limit). Logically they are the same. And you are wrong about whether this will iterate X times regardless of how many items, because it does a `` if iterator.hasNext() returns false. – David Faber Sep 06 '12 at 20:13
  • Ah yes, I see the cfbreak now. I still think it is a less-than-optimal solution. – Jason Dean Sep 06 '12 at 20:21