1

So I'm creating a really simple module to read from a custom table. Nothing fancy, table has two rows:

+-----------+--------------+
+ status_id + status_label +
+-----------+--------------+
+ 1         + option 1     +
+-----------+--------------+
+ 2         + option 2     +
+-----------+--------------+

I'm trying to get them into a <select> element so I set up my Block to get the options:

public function getStatusOptions()
{
    return  $this->statusFactory->create()->getCollection();
}

StatusFactory gets auto generated by (I'm in developer mode so is automatic) fine which is good but when I try and use it in my template like this:

<select name="" id="my-select" class="select">
    <?php foreach ($this->getStatusOptions() as $k => $option) : ?>
        <option id="<?php echo $k; ?>">
            <?php var_dump($option); ?>
        </option>
    <?php endforeach; ?>
</select>

but it returns a fatal error of: Allowed memory size of 792723456 bytes exhausted (tried to allocate 400560128 bytes)

but I'm not sure why .. Everywhere online seems to suggest this is the way to do it (and I'm almost 100% on it because Dependacy Injection is the way it seems with M2).

If you need more code let me know, or if you find a duplicate (I couldn't find a solution that worked for me) then please link :)

UPDATE

I know getCollection works, made another function that also uses ->getSize() and it returns the correct ammount of rows, so.. maybe I'm missing something for calling my collection?

Thanks

2

A thing I notice here is that you use the method for a loop; so every time the foreach() runs, a new collection object will be instantiated, which means - if I am correct - that every time the foreach will start new, and will run infinitely.

A better way would be to store the result in a variable:

<select name="" id="my-select" class="select">
    <?php
    $options = $this->getStatusOptions();
    foreach ($options as $k => $option) : ?>
        <option id="<?php echo $k; ?>">
            <?php var_dump($option); ?>
        </option>
    <?php endforeach; ?>
</select>

This way, the object will only be created once, the collection will only be loaded once and you're safe to go.

Another possibility is to set the collection as a property on your object; change the function as shown below:

public function getStatusOptions()
{
    if(is_null($this->_statusCollection) {
        $this->_statusCollection = $this->statusFactory->create()->getCollection();
    }
    return $this->_statusCollection;
}

Again, you will have only one object instantiated.

You are correct that getCollection() returns a collection object, but deep inside the code the collection class implements the ArrayAccess interface (docs here: http://php.net/manual/de/class.arrayaccess.php), so it is loopable by foreach().

Also keep in mind that var_dump($option); can consume a lot of memory if $option is an object that extends from a default Magento class. In this case, however, it should have a debug() method available, that will consume a lot less memory and can be used like var_dump($option->debug());.

  • 1
    ah fudge muffins this is correct! I should have assigned it to a var and looped the variable ! Can't believe I missed that haha will accept this as correct, as my answer is technically correct, but not the true solution to my error – treyBake Apr 20 '18 at 13:37
1

it turns out ->getCollection() isn't neccesarily the collection data but the collection object. To get data use collection like this:

return $this->statusFactory->getCollection()->getData(); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.