Reputation: 73
I'm building a website with angular.
The site contains a login page, and after the user logs in, there is a routing to the user's profile page, where data stored in Firebase should appear.
For some reason the data appears on the screen just after refreshing the page.
Do you have any idea what the reason is, and how I can fix the problem?
Thank you in advance!
Here is the relevant code in my opinion:
profile.component.html:
<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
<tbody *ngFor="let item of user">
<div>
<tr>
<th>Name:</th>
<td>{{item.name}}</td>
</tr>
<tr>
<th>Email:</th>
<td>{{item.email}}</td>
</tr>
<tr>
<th>Phone Number:</th>
<td>{{item.phone}}</td>
</tr>
</div>
</tbody>
</table>
profile.component.ts:
import { Component, OnInit } from '@angular/core';
import {CrudService} from '../services/crud.service';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: any;
message = '';
errorMessage = '';
error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle
constructor(public authservice: AuthService, private router: Router,public crudservice:CrudService) { }
ngOnInit(){
if(this.authservice.currentUser != null)//We will make sure the user is logged in
{
this.crudservice.get_userInfo().subscribe(data => {
this.user = data.map(c => {
return {
id: c.payload.doc.id,
name: c.payload.doc.data()['name'],
email: c.payload.doc.data()['email'],
phone: c.payload.doc.data()['phone'],
};
})
console.log(this.user);
});
}
}
}
auth.service.ts:
import { Injectable } from '@angular/core';
import { AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
authState: any =null;
constructor(private afu: AngularFireAuth, private router: Router) {
this.afu.authState.subscribe((auth =>{
this.authState = auth;
}))
}
//get fanctions, to get data from firebase
get isUserAnonymousLoggedIn(): boolean{
return (this.authState !== null) ? this.authState.isAnonymous : false
}
get currentUserId(): string{
return (this.authState !== null) ? this.authState.uid : ''
}
get currentUserName(): string{
return this.authState['email']
}
get currentUser(): any{
return (this.authState !== null) ? this.authState : null;
}
get isUserEmailLoggedIn(): boolean{
if((this.authState !== null) && (!this.isUserAnonymousLoggedIn)){
return true
} else{
return false
}
}
//function in use in login.component.ts
loginWithEmail(email: string, password: string){
return this.afu.signInWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
}).catch(error=>{
console.log(error)
throw error
})
}
}
crud.service.ts:
import { Injectable } from '@angular/core';
import { from } from 'rxjs';
import {AngularFirestore} from '@angular/fire/firestore';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class CrudService {
constructor(private authservice: AuthService, public fireservices:AngularFirestore) { }
get_userInfo()
{
return this.fireservices.collection('users').doc(this.authservice.currentUserId).collection('user-info').snapshotChanges();
}
}
login.component.ts:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
email="";
password="";
errorMessage = ''; //validation error handle
error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle
constructor(private authservice: AuthService, private router: Router) { }
ngOnInit(): void {
}
login()
{
this.clearErrorMessage();
if(this.validateForm(this.email, this.password))
{
this.authservice.loginWithEmail(this.email, this.password)
.then(() => {
this.router.navigate(['/profile'])
}).catch(_error =>{
this.error = _error
this.router.navigate(['/login'])
})
}
}
clearErrorMessage()
{
this.errorMessage = '';
this.error = {name: '', message:''};
}
validateForm(email, password)
{
.
.
.
.
}
}
Upvotes: 0
Views: 438
Reputation: 2496
That because subscribe in first return null or undefined.
To resolve this issue your code will be like :
this.crudservice.get_userInfo().subscribe(data => {
if(data != null && data != undefined) {
this.user = data.map(c => {
return {
id: c.payload.doc.id,
name: c.payload.doc.data()['name'],
email: c.payload.doc.data()['email'],
phone: c.payload.doc.data()['phone'],
};
})
console.log(this.user);
}
}
You can also add ngIf in your HTML page
<div *ngIf="user != null" >
<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
<tbody *ngFor="let item of user">
<div>
<tr>
<th>Name:</th>
<td>{{item.name}}</td>
</tr>
<tr>
<th>Email:</th>
<td>{{item.email}}</td>
</tr>
<tr>
<th>Phone Number:</th>
<td>{{item.phone}}</td>
</tr>
</div>
</tbody>
</table>
</div>
More detail is here :
https://rxjs-dev.firebaseapp.com/guide/subscription
Hope useful
Upvotes: 1