Skip to content

Commit 165db07

Browse files
author
bczmarko
committed
load more posts on scroll on series view
1 parent 6771849 commit 165db07

File tree

3 files changed

+60
-30
lines changed

3 files changed

+60
-30
lines changed
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
<div class="series-view">
1+
<div class="series-view" infiniteScroll [isActiveInfiniteScroll]="isActiveInfiniteScroll"
2+
(scrolled)="loadMorePostsFromSeries()">
23
<div class="cards-wrapper grid">
3-
@for (post of postsInSeries$ | async; track post.id) {
4+
@for (post of postsInSeries; track post) {
45
<a [routerLink]="['/post', post.slug]">
56
<p-card class="post-card" header="{{ post.title }}">
67
<ng-template pTemplate="header">
@@ -10,4 +11,10 @@
1011
</a>
1112
}
1213
</div>
14+
15+
@if (paginationInfo.hasNextPage && !isHiddenLoadMore) {
16+
<div class="load-more-posts">
17+
<p-button (click)="loadMorePostsFromSeries()">Load more</p-button>
18+
</div>
19+
}
1320
</div>
Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,54 @@
11
import { Component, inject } from '@angular/core';
2-
import { ActivatedRoute, Params, RouterLink } from '@angular/router';
3-
import { Observable, switchMap } from 'rxjs';
4-
import { Post } from '../../models/post';
2+
import { ActivatedRoute, RouterLink } from '@angular/router';
3+
import { PageInfo, Post } from '../../models/post';
54
import { AsyncPipe } from "@angular/common";
65
import { BlogService } from '../../services/blog.service';
76
import { CardModule } from 'primeng/card';
7+
import { InfiniteScrollDirective } from "../../directives/infinite-scroll.directive";
8+
import { ButtonModule } from "primeng/button";
89

910
@Component({
1011
selector: 'app-series',
1112
standalone: true,
12-
imports: [RouterLink, AsyncPipe, CardModule],
13+
imports: [RouterLink, AsyncPipe, CardModule, InfiniteScrollDirective, ButtonModule],
1314
templateUrl: './series.component.html',
1415
styleUrl: './series.component.scss'
1516
})
1617
export class SeriesComponent {
1718
blogURL!: string;
1819
slug: string = "";
19-
postsInSeries$!: Observable<Post[]>;
20+
postsInSeries: Post[] = [];
21+
paginationInfo: PageInfo = { hasNextPage: true, endCursor: '' };
22+
isHiddenLoadMore: boolean = true;
23+
isActiveInfiniteScroll: boolean = false;
24+
2025
blogService: BlogService = inject(BlogService);
2126
route: ActivatedRoute = inject(ActivatedRoute);
2227

2328
ngOnInit(): void {
2429
this.blogURL = this.blogService.getBlogURL();
25-
this.postsInSeries$ = this.route.params.pipe(
26-
switchMap((params: Params) => {
27-
this.slug = params["slug"];
28-
return this.blogService.getPostsInSeries(this.blogURL, this.slug);
29-
})
30-
);
30+
this.route.params.subscribe(params => {
31+
this.slug = params['slug'];
32+
this.loadPostsInSeries();
33+
})
3134
}
35+
36+
private loadPostsInSeries():void{
37+
this.blogService.getPostsInSeries(this.blogURL, this.slug).subscribe(seriesPageInfo => {
38+
this.paginationInfo = seriesPageInfo.pagination;
39+
this.isHiddenLoadMore = !seriesPageInfo.pagination.hasNextPage;
40+
this.postsInSeries = seriesPageInfo.posts;
41+
})
42+
}
43+
44+
loadMorePostsFromSeries():void {
45+
if (!this.paginationInfo.hasNextPage) return;
46+
this.isHiddenLoadMore = true;
47+
this.blogService.getPostsInSeries(this.blogURL, this.slug, this.paginationInfo.endCursor).pipe(
48+
).subscribe(newPosts => {
49+
this.isActiveInfiniteScroll = true;
50+
this.paginationInfo = newPosts.pagination;
51+
this.postsInSeries = this.postsInSeries.concat(newPosts.posts);
52+
});
53+
}
3254
}

angular-primeng-app/src/app/services/blog.service.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,24 @@ export class BlogService {
106106
);
107107
}
108108

109-
getPostsInSeries(host: string, slug: string): Observable<Post[]> {
110-
return this.apollo
111-
.watchQuery<any>({
112-
query: GET_POSTS_IN_SERIES,
113-
variables: {
114-
host: host,
115-
slug: slug,
116-
},
117-
})
118-
.valueChanges.pipe(
119-
map(({ data }) =>
120-
data.publication.series.posts.edges.map(
121-
(edge: { node: any }) => edge.node
122-
)
123-
)
124-
);
125-
}
109+
getPostsInSeries(host: string, slug: string, after: string = ""): Observable<PostsPageInfo> {
110+
return this.apollo
111+
.watchQuery<any>({
112+
query: GET_POSTS_IN_SERIES,
113+
variables: {
114+
host: host,
115+
slug: slug,
116+
after: after
117+
},
118+
}).valueChanges.pipe(
119+
map(({ data }) => {
120+
const { edges, pageInfo } = data.publication.series.posts;
121+
return {
122+
posts: edges.map((edge: { node: any; }) => edge.node),
123+
pagination: pageInfo
124+
};
125+
}));
126+
}
126127

127128
getSinglePost(host: string, slug: string): Observable<Post> {
128129
return this.apollo

0 commit comments

Comments
 (0)