Headline seems a bit complicated but It's simple. I have a Post model with table and everything, in the PostController I'm passing posts to the view as below
Here in my controller I'm getting my articles from API and passing it to $articles variable and I'm getting my posts from database and I'm passing it to $posts variable
public function index()
{
$articles = Http::withHeaders([
'api-key' => config('services.devto.key'),
])->get('http://dev.to/api/articles/me/published');
$articles = json_decode($articles, true);
return view('posts.index', [
'posts' => Post::latest()->filter(request(['search', 'category', 'author']))->paginate(6)->withQueryString(),
'articles' => $articles
]);
}
I can pass both to the same view and do as below and it works fine
<div >
@foreach ($posts->skip($posts->onFirstPage() ? 3 : 0) as $post)
<x-postCard :post="$post" />
@endforeach
@foreach ($articles as $article)
<x-articlepostcard :article="$article" />
@endforeach
</div>
This gives me 6 of my posts because i paginate them and then right after i get all 10 articles from my API and then in page 2 i get another 6 of my posts and below them the same 10 articles repeated again because i can't paginate them as they're just json in a variable.
Any ideas on how to make my view show posts and articles altogether paginated and sorted by date?
CodePudding user response:
You can create a data transfer object that will represent a post or an article.
For instance (assuming you're using PHP 8):
class ArticleDTO {
public __construct(
public string $title,
public string $content,
public Carbon $published_at,
)
{
}
}
Then, you fetch your articles and your posts, and you instantiate each of them into the DTO and make a collection out of it
$articleCollection = collect();
foreach ($articles as $article) {
$articleCollection->push(
new ArticleDTO(
$article->title,
$article->content,
$article->published_at
)
);
}
// Do the same for the posts
You can then pass the collection, sorted by date, to your view.
return view('posts.index', [
'articles' => $articleCollection->sortBy('published_at'),
]);
Caveat to this solution
In order to keep the pagination working, you might need to manually invoke the paginator but then you'll still load all the data on each request.