Skip to content

Instantly share code, notes, and snippets.

@touhidrahman
Last active January 30, 2022 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save touhidrahman/820ea81a7c9e78cf6a7bb7a20c4f897f to your computer and use it in GitHub Desktop.
Save touhidrahman/820ea81a7c9e78cf6a7bb7a20c4f897f to your computer and use it in GitHub Desktop.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { getPagination } from '@core/utils/pagination.util';
import { Friend } from '@features/friends/models/friend';
import { FriendApiService } from '@features/friends/services/friend-api.service';
import { BehaviorSubject, combineLatest, debounceTime,
EMPTY, interval, Subject, switchMap,
takeUntil, tap } from 'rxjs';
@Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.scss'],
})
export class HomePageComponent implements OnInit {
friends = new BehaviorSubject<Friend[]>([]);
polling = new BehaviorSubject<boolean>(false);
loading = new BehaviorSubject<boolean>(false);
page = new BehaviorSubject<number>(0);
search = new BehaviorSubject<string>('');
private destroyed = new Subject<void>();
constructor(
private activatedRoute: ActivatedRoute,
private api: FriendApiService
) {
this.init();
this.poll();
}
ngOnInit(): void {
this.activatedRoute.queryParams.subscribe({
next: ({ search = '', page = 1 }) => {
this.search.next(search);
const pageNumber = getPagination(page);
this.page.next(pageNumber);
},
});
}
ngOnDestroy(): void {
this.destroyed.next();
this.destroyed.complete();
}
private init() {
//load initial friends and respond to page no & search term changes
combineLatest({ page: this.page.asObservable(), search: this.search.asObservable() })
.pipe(
debounceTime(300),
tap(() => this.loading.next(true)),
switchMap(({ page, search }) => this.api.getFriends(search, page)),
takeUntil(this.destroyed)
)
.subscribe({
next: (friends) => {
this.friends.next(friends);
this.loading.next(false);
this.polling.next(true);
},
});
}
private poll() {
// poll every 5 seconds for location change
const interval$ = this.polling.asObservable().pipe(
switchMap((isPolling) => (isPolling ? interval(5000) : EMPTY))
);
interval$
.pipe(
tap(() => this.loading.next(true)),
switchMap(() =>
this.api.getFriends(this.search.value, this.page.value)
),
takeUntil(this.destroyed)
)
.subscribe({
next: (friends) => {
this.friends.next(friends);
this.loading.next(false);
},
});
}
}
<app-navbar-default>
<app-friend-tracking-status
[tracking]="(polling.asObservable() | async) ?? false"
[loading]="(loading.asObservable() | async) ?? false"
(toggle)="polling.next($event)"
></app-friend-tracking-status>
</app-navbar-default>
<main class="container mx-auto px-4 sm:px-0 pt-6 pb-24 relative">
<app-friend-map
[friends]="(friends.asObservable() | async) ?? []"
></app-friend-map>
<div class="max-w-screen-sm mt-8 mb-12 mx-auto">
<app-friend-search
(searchTermChange)="search.next($event)"
></app-friend-search>
</div>
<div class="grid grid-cols-1 gap-10 sm:grid-cols-2 xl:grid-cols-3">
<app-friend-card
*ngFor="let friend of friends.asObservable() | async"
[friend]="friend"
></app-friend-card>
</div>
</main>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment