组件:
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { AF } from '../angularfire.service';
@Component({
selector: 'app-add-friend',
templateUrl: './add-friend.component.html',
styleUrls: ['./add-friend.component.less']
})
export class AddFriendComponent implements OnInit {
profileInfo = [];
currentUser = [];
requestToggle: boolean = false;
showButtons: boolean = true;
constructor(private afService: AF, private route: ActivatedRoute, private router: Router) {
let id = this.route.snapshot.params['id'];
// Get viewed profile details.
this.afService.getAthleteProfile(id).subscribe((data) => {
if (data.length > 0) {
let details = data[0];
this.profileInfo.push(details);
}
});
// Get current logged in user details.
afService.getCurrentUserInfo().then(currentUserDetails => {
this.currentUser.push(currentUserDetails);
});
}
// Send friend request.
addFriend() {
this.afService.addFriendRequest(this.profileInfo[0].userID, this.currentUser[0].userID, this.profileInfo[0].firstName, this.profileInfo[0].lastName, this.currentUser[0].firstName, this.currentUser[0].lastName).then(() => {
});
}
ngOnInit() {
// Check if friend request has been sent to display appropriate button.
setTimeout (() => {
if (this.currentUser) {
this.afService.getFriendRequests(this.profileInfo[0].userID, this.currentUser[0].userID).subscribe((data) => {
if (data.length > 0) {
this.requestToggle = true;
}
});
this.afService.getFriendRequestsFrom(this.profileInfo[0].userID, this.currentUser[0].userID)
.subscribe(data => {
if (data.length > 0) {
this.requestToggle = true;
}
});
}
// Hides buttons if on own profile.
if (this.profileInfo[0].userID == this.currentUser[0].userID) {
this.showButtons = false;
} else {
this.showButtons = true;
}
}, 1000);
}
}
服务:
import { Injectable } from "@angular/core";
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import "rxjs/add/operator/map";
@Injectable()
export class AF {
public currentUserDetails;
constructor(public af: AngularFireAuth, private database: AngularFireDatabase, private router: Router) {
}
// Get all currently logged in user details.
getCurrentUserInfo() {
return new Promise((resolve, reject) => {
this.af.authState.subscribe(authData => {
let email = authData.email;
let array = this.database.list('registeredUsers', {
query: {
orderByChild: 'email',
equalTo: email
}
}).subscribe(data => {
let currentUserDetails = data[0];
resolve(currentUserDetails);
});
});
});
}
// Get all users details.
getAllAthletes(): Observable<any> {
return this.database.list('registeredUsers');
}
// Get useer details for the current profile route.
getAthleteProfile(userID) {
return this.database.list('registeredUsers', {
query: {
orderByKey: userID,
equalTo: userID
}
})
}
// Register new user.
registerUser(email, password) {
return this.af.auth.createUserWithEmailAndPassword(email, password);
}
// Add new user details to database.
addUserEntry(uid, fname, lname, email) {
return this.database.object('registeredUsers/' + uid).set({
firstName: fname,
lastName: lname,
email: email,
userID: uid,
bio: "Your short bio goes here...",
phone: 5555555555
});
}
// Add friend request to both parties.
addFriendRequest(profileUID, currentUID, profileFirstName, profileLastName, currentFirstName, currentLastName) {
return this.database.object('registeredUsers/' + currentUID + '/friends/requests/requestTo/' + profileUID).set({
requestTo: profileUID,
firstName: profileFirstName,
lastName: profileLastName
}).then(() =>
this.database.object('registeredUsers/' + profileUID + '/friends/requests/requestFrom/' + currentUID).set({
requestFrom: currentUID,
firstName: currentFirstName,
lastName: currentLastName
})
)}
/* (TODO): Consolidate lines 81-99. Replace the paths with variables set in the components.
---*
---*/
// Check if user sent a friend request to user being viewed.
getFriendRequests(profileUID, currentUID) {
return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestTo/' + profileUID)
}
// Check if user received a friend request from user being viewed.
getFriendRequestsFrom(profileUID, currentUID) {
return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestFrom/' + profileUID)
}
// Get all sent friend requests.
getPendingFriendRequests(currentUID) {
return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestTo/');
}
// Get all received friend requests.
getPendingFriendRequestsFrom(currentUID) {
return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestFrom/');
}
// Update the user account info.
updateUserEntry(uid, fname, lname, phone, bio) {
return this.database.object('registeredUsers/' + uid).update({
firstName: fname,
lastName: lname,
phone: phone,
bio: bio
});
}
// Login
loginWithEmail(email, password) {
return this.af.auth.signInWithEmailAndPassword(email, password).then(()=> {
this.router.navigate(['/dashboard']);
}).catch(function(error) {
var errorMessage = error.message;
})
}
// Logout
logout() {
this.af.auth.signOut().then(() =>
this.router.navigate(['/login'])
)}
}
接近最后,我将函数包装在1秒setTimeout
函数中,因为需要填充数组currentUser
才能使其正常运行。数组总是被填充,但速度不够快,因此该函数永远不会在没有setTimeout
的情况下运行。
有没有办法告诉Angular “在填充此数组后运行此函数”?
,而不是使用setTimeout
答案 0 :(得分:2)
首先,在服务中不需要Promise
,你只需返回observable:
import 'rxjs/add/operator/mergeMap';
getCurrentUserInfo() {
return this.af.authState.mergeMap(authData => {
return this.database.list('registeredUsers', {
query: {
orderByChild: 'email',
equalTo: authData.email
}
});
}).map(data => {
let currentUserDetails = data[0];
resolve(currentUserDetails);
});
}
注意:如果你不知道可观察物是如何工作的,你应该看看 一些教程。
之后,您可以在组件中使用它。我们知道,我们需要currentUser
和profileInfo
bevor我们可以执行您的功能。这意味着,两个可观察者都需要得到补充:
import 'rxjs/add/observable/forkJoin';
Observable.forkJoin(
this.afService.getAthleteProfile(id),
this.afService.getCurrentUserInfo()
).subscribe((results) => {
results[0]; //This is the result of getAthleteProfile
results[1]; //This is the result of getCurrentUserInfo
//Now, push the values into the arrays
yourFunction(); //and execute your function here
});
注意:不要忘记导入您的Observable操作符:
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/mergeMap';