I trying to make a similar app for learning after I took the tutorial, The problem is in the first visit or when I reload the page, everything is ok but when I came from the login page or register page using router navigation (this.router.navigate([‘/’])) then the data didn’t load up until I click somewhere, and I mean do something on the webpage and the data will show up.
task-list.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import { MeteorObservable } from 'meteor-rxjs';
import { InjectUser } from "angular2-meteor-accounts-ui";
import { PaginationService } from 'ng2-pagination';
import { Counts } from 'meteor/tmeasday:publish-counts';
import 'rxjs/add/operator/combineLatest';
import { Tasks } from '../../../../both/collections/tasks.collection';
import { Task } from '../../../../both/models/task.model';
import template from './tasks-list.component.html';
import style from './tasks-list.component.scss';
interface Pagination {
limit: number;
skip: number;
}
interface Options extends Pagination {
[key: string]: any
}
@Component({
selector: 'tasks-list',
template,
styles: [style]
})
@InjectUser('user')
export class TasksListComponent {
tasks: Observable<Task[]>;
user: Meteor.User;
pageSize: Subject<number> = new Subject<number>();
curPage: Subject<number> = new Subject<number>();
createdAtOrder: Subject<number> = new Subject<number>();
tasksSize: number = 0;
name: Subject<string> = new Subject<string>();
autorunSub: Subscription;
optionsSub: Subscription;
tasksSub: Subscription;
constructor(
private paginationService: PaginationService
) {}
ngOnInit() {
this.optionsSub = Observable.combineLatest(
this.pageSize,
this.curPage,
this.createdAtOrder,
this.name
).subscribe(([pageSize, curPage, createdAtOrder, name]) => {
const options: Options = {
limit: pageSize as number,
skip: ((curPage as number) - 1) * (pageSize as number),
sort: { createdAt: createdAtOrder as number }
};
this.paginationService.setCurrentPage(this.paginationService.defaultId(),curPage as number);
if(this.tasksSub) {
this.tasksSub.unsubscribe();
}
this.tasksSub = MeteorObservable.subscribe('tasks', options, name).subscribe(() => {
this.tasks = Tasks.find({}, {
sort: {
createdAt: createdAtOrder
}
}).zone();
});
});
this.paginationService.register({
id: this.paginationService.defaultId(),
itemsPerPage: 10,
currentPage: 1,
totalItems: this.tasksSize
});
this.pageSize.next(10);
this.curPage.next(1);
this.createdAtOrder.next(-1);
this.name.next('');
this.autorunSub = MeteorObservable.autorun().subscribe(() => {
this.tasksSize = Counts.get('numberOfTasks');
this.paginationService.setTotalItems(this.paginationService.defaultId(), this.tasksSize);
})
}
onPageChanged(page: number): void {
this.curPage.next(page);
}
isOwner(task: Task) {
return this.user && this.user._id === task.owner;
}
isDone(task: Task) {
return task.done === true;
}
removeTask(task: Task) {
Tasks.remove(task._id);
}
changeTaskState(task: Task) {
if(this.user && this.user._id === task.owner){
Tasks.update(task._id, {$set: {done: !task.done}});
} else {
alert('You are not the owner of this task!');
return;
}
}
search(value: string): void {
this.curPage.next(1);
this.name.next(value);
}
changeSortOrder(nameOrder: string): void {
this.createdAtOrder.next(parseInt(nameOrder));
}
ngOnDestroy(): void {
this.tasksSub.unsubscribe();
this.optionsSub.unsubscribe();
this.autorunSub.unsubscribe();
}
}
login.component.ts
import {Component, OnInit, NgZone} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { Meteor } from 'meteor/meteor';
import { InjectUser } from "angular2-meteor-accounts-ui";
import template from './login.component.html';
import style from './login.component.scss';
@Component({
selector: 'login',
template,
styles: [style]
})
@InjectUser('user')
export class LoginComponent implements OnInit {
user: Meteor.User;
loginForm: FormGroup;
errorMessage: string;
constructor(
private router: Router,
private zone: NgZone,
private formbuilder: FormBuilder
) {}
ngOnInit() {
// if(this.user) {
// this.router.navigate(['/']);
// }
this.loginForm = this.formbuilder.group({
email: ['', Validators.required],
password: ['', Validators.required]
});
this.errorMessage = '';
}
doLogin(): void {
if(this.loginForm.valid) {
Meteor.loginWithPassword(this.loginForm.value.email, this.loginForm.value.password, (err) => {
if(err) {
this.zone.run(() => {
this.errorMessage = err;
})
} else {
this.router.navigate(['/']);
}
})
}
}
}
And the task-list.component.hml
<div>
<div class="row"><tasks-form></tasks-form></div>
<div id="search-box" class="row">
<div class="col-md-10 offset-md-1">
<input type="text" class="form-control" #searchText placeholder="Search task" (keyup)="search(searchText.value)">
</div>
</div>
<div id="tasks-list">
<h1 class="title-text">Tasks:</h1>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Sort by date: </label>
<select class="form-control" #sort (change)="changeSortOrder(sort.value)">
<option value="-1" selected>Descending</option>
<option value="1">Ascending</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" *ngFor="let task of tasks | async">
<div class="card">
<div class="card-block">
<a class="card-title" [routerLink]="['/task', task._id]"><h4>{{task.name}}</h4></a>
<p class="card-text">{{task.description}}</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
<div class="card-block">
<button class="btn"
[ngClass]="isDone(task) ? 'btn-success' : 'btn-warning'"
(click)="changeTaskState(task)"
[disabled]="!isOwner(task)">
{{task | doneButton}}
</button>
<button *ngIf="isOwner(task)" class="btn btn-danger delete-button" (click)="removeTask(task)">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div id="pagination">
<pagination-controls
(pageChange)="onPageChanged($event)">
</pagination-controls>
</div>
</div>
</div>
here is the gif that show the error, notice that then data will only show up when I click somewhere in the page
Please help me with this problem, thank you.
You can look for the project here, if someone have time, please help me with this, this error is very weird…
https://github.com/lednhatkhanh/simple-todos