从 mongoDB 获取数据并使用 Angular 和 NodeJs 在屏幕上打印
Posted
技术标签:
【中文标题】从 mongoDB 获取数据并使用 Angular 和 NodeJs 在屏幕上打印【英文标题】:Get data from mongoDB and print on screen using Angular and NodeJs 【发布时间】:2017-11-22 06:18:51 【问题描述】:我有一个使用 MongoDB、Angular 和 NodeJs 的小项目。
注册或登录成功后,我的应用程序将在屏幕上显示有关用户的所有信息(姓名、年龄)。
注册并显示完成(感谢@Mikas)但是当我登录时,它只显示用户名,不显示年龄。 请帮我修复它。谢谢你。
我的 server.js
// IMPORTS
var express = require('express');
var app = express();
var fs = require('fs');
var http = require('http');
var https = require('https');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken');
var config = require('./config');
var bodyParser = require('body-parser');
var User = require('./user');
// connect database
mongoose.connect(config.DATABASE);
// GLOBAL MIDDLEWARE
app.use(express.static('public'));
app.use(bodyParser.json(limit: '50mb'));
app.use(bodyParser.urlencoded(limit: '50mb', extended: true));
app.use(function(req, res, next)
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, x-access-token');
// intercept OPTIONS method
if ('OPTIONS' == req.method)
res.sendStatus(200);
else
next();
);
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
// MS API FUNCTIONS
/**
* Call MS face detection
*
* @param * imageData image as dataURL
* @param * onSuccess success callback
* @param * onError error callback
*/
function callMsDetect(imageData, onSuccess, onError)
var msDetectOptions =
host: config.FACE_API_HOST,
method: 'POST',
port: 443,
path: config.FACE_API_PATH_DETECT,
headers:
'Content-Type': 'application/octet-stream',
'Content-Length': Buffer.byteLength(imageData),
'Ocp-Apim-Subscription-Key': config.FACE_API_KEY
;
var msDetectReq = https.request(msDetectOptions, function(msDetectResponse)
msDetectResponse.setEncoding('utf8');
msDetectResponse.on('data', function(msDetectData)
onSuccess(JSON.parse(msDetectData));
);
);
msDetectReq.on('error', onError);
msDetectReq.write(imageData);
msDetectReq.end();
/**
*
* @param * faceId1 face1 to compare
* @param * faceId2 face2 to compare
* @param * onSuccess success callback
* @param * onError error callback
*/
function callMsCompare(faceId1, faceId2, onSuccess, onError)
var msVerifyOptions =
host: config.FACE_API_HOST,
method: 'POST',
port: 443,
path: config.FACE_API_PATH_VERIFY,
headers:
'Ocp-Apim-Subscription-Key': config.FACE_API_KEY
var msVerifyReq = https.request(msVerifyOptions, function(msVerifyResponse)
msVerifyResponse.setEncoding('utf8');
msVerifyResponse.on('data', function(msVerifyData)
onSuccess(JSON.parse(msVerifyData));
);
)
msVerifyReq.on('error', onError);
msVerifyReq.write(JSON.stringify(faceId1: faceId1, faceId2: faceId2));
msVerifyReq.end();
// PUBLIC API ENDPOINTS
// login endpoint
app.post('/login', function(req, res)
// possible login methods: image or password
var imageData,
password = req.body.password;
// if neither password nor image is sent, send 400;
if(!req.body.password && !req.body.image)
res.statusCode = 400;
res.json('message': 'Either image or password is required');
return;
// select user from database
User.findOne(
username: req.body.username
).select('user username faceId password').exec(function(err, user)
if(err || !user)
res.statusCode = 403;
res.json(message:'user not found');
return;
// password login
if(password)
// check password
var validPassword = user.comparePassword(password);
if(!validPassword)
// if password does not match, send 403
res.statusCode = 403;
res.json(message: 'Authentication failed. Wrong username / password.');
else
// if user is found and password is right, create a token
var token = jwt.sign(
username: user.username
, config.SECRET);
// send the token
res.json(
message: 'Enjoy your token!',
token:token
);
else
// get image as binary data, so it can be sent to MS
if(req.body.image)
imageData = Buffer.from(req.body.image.split(",")[1], 'base64');
// image login
if (imageData)
// detect faces on the login image
callMsDetect(imageData,
function(msDetectData)
// check for the first face
// TODO: send error when more than one face is recognized and let the user pick one
if(msDetectData[0])
// compare the recognized face to the saved one
callMsCompare(user.faceId, msDetectData[0].faceId,
function(msCompareData)
if(msCompareData.isIdentical && msCompareData.confidence >= config.FACE_API_CONFIDENCE_TRESHOLD)
//if faces match, create a token
var token = jwt.sign(
username: user.username
, config.SECRET);
//return the information including token as JSON
res.json(
message: 'Login succesful',
token:token
);
else
// if faces do not match, send 403
res.statusCode = 403;
res.json('message': 'image login failed - face could not be verified');
,
function(error)
// if an error occurs during the compare, send 500
res.statusCode = 500;
res.json('message': 'Failed');
);
else
// if no face can be recognized on the login image, send 400
res.statusCode = 400;
res.json('message': 'Failed - No data');
,
function(error)
// if an error occurs during the detection, send 500
res.statusCode = 500;
res.json('message':'image login failed - face detection failed');
);
else
// if neither password nor valid image data is given, send error
res.statusCode = 400;
res.json(message: 'Either password or image is required');
)
);
// register endpoint
app.post('/register', function(req, res)
// if username or password is missing, send 400
if(!req.body.user.username || !req.body.user.password)
res.statusCode = 400;
res.json('message': 'username and password are required');
return;
// create new user object
var user = new User();
user.username = req.body.user.username;
user.age = req.body.user.age;
user.password = req.body.user.password;
// if image is given
if(req.body.image)
// call face detection
callMsDetect(Buffer.from(req.body.image.split(",")[1], 'base64'),
function(msDetectData)
var faceMessage = '';
// face will only be saved if only one face is recognized
// if no face or more than one face is recognized, the user will be informed
// the account will be created without any faceId anyways
if(msDetectData.length === 1)
user.faceId = msDetectData[0].faceId;
else if(!msDetectData.length)
faceMessage = 'No face was recognized.'
else
faceMessage = 'More than one face was recognized.'
user.save(function(error)
if(error)
// if an error occurs during save, send 500
res.statusCode = 500;
res.json('message':'error during save');
return;
// login user
var token = jwt.sign(
username: user.username
, config.SECRET);
res.json(
message: 'User was created. ' + faceMessage,
token: token
);
);
,
function(error)
// if an error occurs during face detection, inform user
// the account will be created without any faceId anyways
user.save(function(error)
var faceMessage = 'Face recognition failed';
if(error)
// if an error occurs during save, send 500
res.statusCode = 500;
res.json(message:JSON.stringify(error));
return;
// login user
var token = jwt.sign(
username: user.username
, config.SECRET);
res.json(
message: 'User was created. ' + faceMessage,
token: token
);
);
);
// if no image was sent, just create the account
else
user.save(function(error)
if(error)
// if an error occurs during save, send 500
res.statusCode = 500;
res.json(message:'Error during save');
return;
var token = jwt.sign(username: user.username, config.SECRET);
res.json(message:'user created',token: token);
);
);
// PRIVATE API ENDPOINTS
// interceptor for private endpoints
app.use(function(req, res, next)
//check header or url parameters or post parameters for token
var token = req.body.token || req.query['token'] || req.headers['x-access-token'];
//decode token
if(token)
//verifiy secret
jwt.verify(token, config.SECRET, function(err, decoded)
if(err)
return res.status(401).send(
message: 'Failed to authenticate token.'
);
else
//if everything is good, save to request for use in other reoutes
req.user = decoded;
next();
)
else
//if there is no token
//return an HTTP response of 403 (access forbidden ) and an error message
return res.status(403).send(
message: 'No token provided.'
);
);
// home endpoint: just some test stuff to check that private APIs actually work
app.get('/home', function(req, res)
res.json('message': 'As a logged in user, you are allowed to see this content. On this page, you can change your securtity information. You can update your password and your login image.');
);
// update password endpoint: update users password
app.post('/updatePassword', function(req, res)
if(!req.body.oldPassword || !req.body.newPassword)
res.statusCode = 400;
res.json(message: 'old password and new password are required');
return;
// get user from token
User.findOne(
username: req.user.username
).select('user username faceId password').exec(function(err, user)
if(err || !user)
// if no user is found, send 400
res.statusCode = 400;
res.json(message:'user not found');
// if user is found, check for password
var validPassword = user.comparePassword(req.body.oldPassword);
if(validPassword)
// if password is valid, set new password and save
user.password = req.body.newPassword;
user.save(function(error)
if(error)
// if an error ouccurs during save, send 500
res.statusCode = 500;
res.json('message':'error during save');
res.json(message:'Password changed');
);
else
//if password is invalid, send 403
res.statusCode = 403;
res.json(message: 'Authentication failed. Wrong old password.');
);
);
// udpate image endpoint: update user image
app.post('/updateImage', function(req, res)
if(!req.body.image)
// if no image was sent, send 400
res.statusCode = 400;
res.json(message: 'image is required');
return;
// get user from token
User.findOne(
username: req.user.username
).select('user username faceId').exec(function(error, user)
if(error || !user)
// if no user is found, send 400
res.statusCode = 400;
res.json(message:'user not found');
return;
// call face detection with new face
callMsDetect(Buffer.from(req.body.image.split(",")[1], 'base64'),
function(msDetectData)
if(msDetectData.length === 1)
user.faceId = msDetectData[0].faceId;
user.save(function(error)
if(error)
// if error occurs during save, send 500
res.statusCode = 500;
res.json('message':'error during save');
return;
res.json(
message: 'Image was updated.',
);
);
// if no face or more than one face was recognized, send 400
// TODO: give user the opportunity to pick one of them in frontend
else if(!msDetectData.length)
res.statusCode = 400;
res.json(message: 'No face was recognized.')
else
res.statusCode = 400;
res.json(message: 'More than one face was recognized.')
,
function(error)
// if an error occurs during face detection, send 500
res.statusCode = 500;
res.json(message: 'image update failed - face recognition error');
);
);
);
// start server
var server = app.listen(8081, function ()
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
)
user.js的一些代码
//user schema
var UserSchema = new Schema(
username: type: String, required:true, index: unique:true,
age: type: String, required:true, index: unique:true,
faceId: type: String, required:false,
password: type: String, required:true, select: false,
);
登录组件
import Component, ViewChild, OnInit, Inject, ChangeDetectorRef from '@angular/core';
import Http from '@angular/http';
import UserRestService from '../../services/user-rest.service';
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
imageUrl;
username;
password;
loginMethod: string = 'camera';
constructor(private router: Router, private userRestService: UserRestService, private auth: AuthService, private ref: ChangeDetectorRef)
ngOnInit()
// login method
login()
// set params: password or imageUrl, depending on chosen loginMethod
var params: any =
username: this.username
;
if(this.loginMethod === 'password')
params.password = this.password;
else
params.image = this.imageUrl;
// perform http call
this.userRestService.login(
username: this.username,
password: this.password,
image: this.imageUrl
)
.subscribe( data =>
// on success set token and user data
var token = data.token;
this.auth.setToken(token);
this.auth.setUser(username: this.username, age: this.age);
// navigate to home page
this.router.navigate(['/home']);
);
// image changed handler for embedded components (image picker, camera snapshot)
imageChanged(data)
this.imageUrl = data;
this.ref.detectChanges();
我打印出来的是:
<div *ngIf="user">
<p>
greeting user.room user.age
</p>
</div>
【问题讨论】:
你使用了这个age: this.age
同时this.age
是未定义的
我试过this.use.age
但没有完成
你也不能这样做。您需要像为 username
和 password
所做的那样创建一个变量 age
。
【参考方案1】:
您可能必须将从您的数据库中检索到的user
传递给您的响应对象:
res.json(
message: 'Enjoy your token!',
token:token,
user: user
);
【讨论】:
您是否尝试过传递age
属性:User.findOne( username: req.body.username , ' user username faceId password age ', function(err, user) etc. );
?以上是关于从 mongoDB 获取数据并使用 Angular 和 NodeJs 在屏幕上打印的主要内容,如果未能解决你的问题,请参考以下文章
使用 mongoose 从 Atlas Mongodb 获取数据到 Angular 应用程序
MEAN STACK angular 2:从打字稿中的多个api获取数据
无法使用 express API 和节点 JS(Angular 4)将数据发布到 mongodb