Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LiveComponent] : Infinite scroll from tutorial not working properly #2497

Open
jonathangreco opened this issue Jan 9, 2025 · 1 comment
Labels

Comments

@jonathangreco
Copy link

I Followed the infinite scroll tutorial which i managed to make it work for step 1. But the step 2 (remove the load more button) is not working as expected.

I have a page which need to load posts (like a blog) and I have about 7 200 of them. An infinite scroll seems a good way to start.

I tried to trick the code a little or do some stuff, be warned that the code you'll see maybe incorrect but I tried so many things ....

<div class="ContentGrid" {{ attributes.defaults(stimulus_controller('appear')) }}>
    <div id="contents" style="display: flex; gap: 1rem; flex-direction: column;" class="p-4">
        <div class="ContentGrid_items row g-1">
            {% if page > 1 %}
                <article class="ContentGrid_item" id="page--{{ page - 1 }}"></article>
            {% endif %}

            {% for item in this.items %}
                <article class="ContentGrid_item card col-12 col-lg-3 border-0" data-live-ignore="true" style="--i: {{ item.id }};">
                    <div class="card-body bgcolor-4bbeff text-white">
                        <data class="ContentGrid_text" value="{{ item.id }}">{{ item.text }}</data>
                    </div>
                </article>
            {% endfor %}

            {% if this.hasMore %}
                {% for i in 1..per_page %}
                    <article id="item--{{ this.items[i-1].id }}"
                             data-live-ignore="true"
                             style="--i: {{ this.items[i-1].id }};"
                             class="ContentGrid_item card col-12 col-lg-3 border-0">
                        <div class="card-body bgcolor-4bbeff text-white">
                            <data class="ContentGrid_text" value="">{{ this.items[i-1].text }}</data>
                        </div>
                    </article>
                {% endfor %}
            {% endif %}
        </div>
    </div>

    <div
            data-appear-target="loader"
            data-action="appear->live#action"
            data-live-action-param="debounce(750)|more"
            style="--i: {{ (page * per_page)}};">
        loader
    </div>
</div>

<?php

declare(strict_types=1);

namespace App\Application\Twig\Components;

use App\Repository\ContentRepository;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
use Traversable;

#[AsLiveComponent('ContentGrid')]
class ContentGrid
{
    use ComponentToolsTrait;
    use DefaultActionTrait;

    private Paginator $items;

    public function __construct(private ContentRepository $contentRepository)
    {
    }

    private const PER_PAGE = 10;

    #[LiveProp]
    public int $page = 1;

    #[LiveAction]
    public function more(): void
    {
        ++$this->page;
    }

    public function hasMore(): bool
    {
        return \count($this->items) > ($this->page * self::PER_PAGE);
    }

    #[ExposeInTemplate('per_page')]
    public function getPerPage(): int
    {
        return self::PER_PAGE;
    }


    public function getItems(): Traversable
    {
        $this->items = new Paginator($this->contentRepository->getContentQueryBuilder($this->page, self::PER_PAGE));

        return $this->items->getIterator();
    }
}

In the first load of the page I have my 10 first items, and the first call of the "more" endpoint.

But each time I scroll down to the data-appear-target, my last ten articles are overwritten instead of adding 10 more.

If i put those 3 lines :

            data-appear-target="loader"
            data-action="appear->live#action"
            data-live-action-param="debounce(750)|more"

Like the tutorial (inside the for, within the first item) then a more degraded experience I face since each 10th item will keep those data attribute and if I scroll top one of them it will continue to load more and more items by

I'm lost here, thanks for help (I just need one basic infinite scroll from a doctrine Entity Contents table)

@jonathangreco jonathangreco added the Bug Bug Fix label Jan 9, 2025
@smnandre
Copy link
Member

You should start from the code of the step 2. https://ux.symfony.com/demos/live-component/infinite-scroll-2

For instance, the code of the fake block (to mimic the previous last one) is different from yours

            {# 🐯- Last result from previous page #}

            {% if page > 1 %}

                <article id="item--{{ page - 1 }}-{{ per_page }}"></article>

            {% endif %}

@smnandre smnandre removed the Bug Bug Fix label Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants