gpt4 book ai didi

javascript - 无法以 Angular 显示用户名

转载 作者:行者123 更新时间:2023-12-01 01:50:39 25 4
gpt4 key购买 nike

我已经使用 jwt 标记化实现了身份验证,登录后我想在导航栏上显示用户名,但它没有显示任何内容,并在控制台上给出错误“错误类型错误:无法读取未定义的属性“用户名””,但刷新后页面显示用户名,但在控制台上仍然给出相同的错误。

这是我的代码

NavbarComponent.ts

import { Component, OnDestroy } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { User } from '../../shared/user';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { AdminAuthGuard } from '../../guards/admin.auth.guard';
import { Subscription } from 'rxjs/Subscription';

@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent {


user$: any;

constructor(private authService: AuthService, private router: Router, private adminGuard: AdminAuthGuard) {
this.authService.getProfile().subscribe((user) => {
console.log('fsdf' + user.user.email);
this.user$ = user.user;
});
}



onLogoutClick() {
// console.log('this.user' + this.user$.email);
this.authService.logout();
this.router.navigate(['/']);
}

}

我在其中打印用户名的 html 代码。

<nav class="navbar navbar-expand-md navbar-light bg-light fixed-top">

<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" routerLink="/home">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="!authService.loggedIn()" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}" routerLink="/login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="!authService.loggedIn()" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}" routerLink="/register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/shopping-cart">Shopping Cart</a>
</li>

<li *ngIf="authService.loggedIn()" ngbDropdown class="nav-item dropdown">
<a ngbDropdownToggle class="nav-link dropdown-toggle" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ user$.username }}</a>
<div ngbDropdownMenu class="dropdown-menu " aria-labelledby="dropdown01">
<a class="dropdown-item" routerLink="/my/orders">My Orders</a>
<a class="dropdown-item" routerLink="/profile">Profile</a>

<a class="dropdown-item" routerLink="/admin/orders">Manage Orders</a>
<a class="dropdown-item" routerLink="/admin/products">Manage Products</a>
<button class="dropdown-item" (click)="onLogoutClick()">Logout</button>
</div>
</li>
</ul>

</div>
</nav>

身份验证服务代码。重点关注 getProfile() 方法

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { Http, Headers, RequestOptions } from '@angular/http';
// import { map } from "rxjs/operators";
// import { map } from 'rxjs/operators';

import { switchMap } from 'rxjs/operators';
import { tokenNotExpired } from 'angular2-jwt';
import { User } from '../shared/user';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/observable/of';
@Injectable()
export class AuthService {
private subject = new Subject<any>();
domain = 'http://localhost:3000';
authToken;
user;
options;

constructor(private http: Http) { }

registerUser(user) {
return this.http.post(this.domain + '/authentication/register', user).map(res => res.json());
}

createAuthenticationHeaders() {
this.loadToken();
this.options = new RequestOptions({
headers : new Headers({
'Content-Type': 'application/json',
'authorization': this.authToken
})
});

}

loadToken() {
this.authToken = localStorage.getItem('token');
}
checkUsername(username) {
return this.http.get(this.domain + '/authentication/checkUsername/' + username).map(res => res.json());
}

checkEmail(email) {
return this.http.get(this.domain + '/authentication/checkEmail/' + email).map(res => res.json());
}

login(user) {
return this.http.post(this.domain + '/authentication/login', user).map(res => res.json());
}



logout() {
this.authToken = null;
this.user = null;
localStorage.clear();
}
storeUserData(token, user) {
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}

getProfile() {
this.createAuthenticationHeaders();
return this.http.get(this.domain + '/authentication/profile', this.options).map(res => res.json());
}



loggedIn() {
return tokenNotExpired();
}

}

这是 http 路由 API,它从 Node.js 编写的 mongodb 数据库中获取用户。重点关注 '/profile' 方法的 get(),它返回一个 Observable。

const User = require('../models/user'); // Import User Model Schema

const jwt = require('jsonwebtoken');
const config = require('../config/database');

module.exports = (router) => {
/* ==============
Register Route
============== */
router.post('/register', (req, res) => {
// Check if email was provided
if (!req.body.email) {
res.json({ success: false, message: 'You must provide an e-mail' }); // Return error
} else {
// Check if username was provided
if (!req.body.username) {
res.json({ success: false, message: 'You must provide a username' }); // Return error
} else {
// Check if password was provided
if (!req.body.password) {
res.json({ success: false, message: 'You must provide a password' }); // Return error
} else {
// Create new user object and apply user input
let user = new User({
email: req.body.email.toLowerCase(),
username: req.body.username.toLowerCase(),
password: req.body.password
});
// Save user to database
user.save((err) => {
// Check if error occured
if (err) {
// Check if error is an error indicating duplicate account
if (err.code === 11000) {
res.json({ success: false, message: 'Username or e-mail already exists' }); // Return error
} else {
// Check if error is a validation rror
if (err.errors) {
// Check if validation error is in the email field
if (err.errors.email) {
res.json({ success: false, message: err.errors.email.message }); // Return error
} else {
// Check if validation error is in the username field
if (err.errors.username) {
res.json({ success: false, message: err.errors.username.message }); // Return error
} else {
// Check if validation error is in the password field
if (err.errors.password) {
res.json({ success: false, message: err.errors.password.message }); // Return error
} else {
res.json({ success: false, message: err }); // Return any other error not already covered
}
}
}
} else {
res.json({ success: false, message: 'Could not save user. Error: ', err }); // Return error if not related to validation
}
}
} else {
res.json({ success: true, message: 'Acount registered!' }); // Return success
}
});
}
}
}
});

router.get('/checkEmail/:email', (req, res) => {
if (!req.params.email) {
res.json({ success: false, message: 'email not provided'});
} else {
User.findOne({ email: req.params.email}, (err, user) => {
if (err) {
res.json({ success: false, message: err});
} else {
if (user) {
res.json({ success: false, message: 'email taken'});
} else {
res.json({ success: true, message: 'email available'});
}
}
});
}
});

router.get('/checkUsername/:username', (req, res) => {
if (!req.params.username) {
res.json({ success: false, message: 'username not provided'});
} else {
User.findOne({ username: req.params.username}, (err, user) => {
if (err) {
res.json({ success: false, message: err});
} else {
if (user) {
res.json({ success: false, message: 'username taken'});
} else {
res.json({ success: true, message: 'username available'});
}
}
});
}
});

router.post('/login', (req, res) => {
if (!req.body.username) {
res.json({ success: false, message: 'No username was provided'});
} else {
if (!req.body.password) {
res.json({ success: false, message: 'No password was provided'});
} else {
User.findOne({ username: req.body.username.toLowerCase() }, (err, user) => {
if (err) {
res.json({ success: false, message: err});
} else {
if (!user) {
res.json({ success: false, message: 'No user exist'});
} else {
const validPassword = user.comparePassword(req.body.password);
if (!validPassword) {
res.json({ success: false, message: 'password invalid'});
} else {
const token = jwt.sign({userId: user._id}, config.secret, {expiresIn: '24h'});
res.json({ success: true, message: 'Success!', token: token, user: {username: user.username}});
}
}
}
});
}
}
});

// MIDDLEWARE TO INTERCEPT HEADERS
// THIS MIDDLEWARE DECRYPTS THE TOKEN
router.use((req, res, next) => {
const token = req.headers['authorization']; // whenever a request coming from angular2 with headers attached it is going to search fot this header
if (!token) {
res.json({ success: false, message: 'No token provided'});
} else {
jwt.verify(token, config.secret, (err, decoded) => {
if (err) {
res.json({ success: false, message: 'invalid token' + err});
} else {
req.decoded = decoded;
next();
}
});
}
})
// ANY ROUTES COMING AFTER THIS MIDDLEWARE WILL PASS THROUGH THE SAME

// BELOW METHOD TAKES THE DECRYPTED TOKEN FIND THE USER
router.get('/profile', (req, res) => {
User.findOne({ _id: req.decoded.userId }).select('username email isAdmin').exec((err, user) => {
if (err) {
res.json({ success: false, message: err});
} else {
if (!user) {
res.json({ success: false, message: 'user not found'});
} else {
res.json({ success: true, user: user });
}
}
});
});

return router; // Return router object to main index.js
}

最佳答案

尝试使用安全导航运算符或*ngIf,因为您正在向API发出请求并异步获取数据。尝试如下,

   <a  ngbDropdownToggle class="nav-link dropdown-toggle"  id="dropdown01" data-toggle="dropdown" aria-haspopup="true"  aria-expanded="false">{{ user$?.username }}</a>

关于javascript - 无法以 Angular 显示用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51574459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com