[英]Angular5 How to use Http Observable
我在Angular5上遇到HTTP請求問題。 我有兩個組件(“ LoginComponent ”,“ WellcomeComponent ”)和一個服務(“ AuthService ”)。
我正在使用auth servise處理HTTP請求,並且此服務也是兩個組件之間的橋梁。
由於可以觀察到的事情,我可以從service獲取和發布請求,但不能正確使用結果。 我不是經驗豐富的Angular開發人員,所以找不到解決方案。
所以現在,我正在逐步解釋。 我將在此處編寫所有代碼,所有步驟均由代碼中的..Step_文本簽名,因此您可以按照此符號執行所有步驟。
LoginComponent
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html'
})
export class LoginComponent {
loginUserData = {}
constructor(
private _auth: AuthService,
public router:Router ){
//SOMETHING
}
//CLICK FORM SUBMIT BUTTON
public onSubmit(values:Object):void {
//SET USER DATA WITH FORM VALUES
console.log("LoginStep_1 - Hello")
this._auth.getToken(this.loginUserData)
// CHECK TOKEN
// IF VERIFIED
console.log('LoginStep_2 - Token Verified');
this._auth.setUserData(this.loginUserData['username']);
console.log('LoginStep_3 - SetUserData Finished');
this.router.navigate(['/wellcome'])
console.log("LoginStep_4 - Navigated");
}
}
驗證服務
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
@Injectable()
export class AuthService {
private _tokenUrl = "http://localhost:8000/api/auth/token/";
private getUserInfoUrl = "http://127.0.0.1:8000/api/userInfo/?username="
private userInfo : any;
constructor(
private http: HttpClient,
private _router: Router
) { }
getToken(user){
console.log("getToken_Step1 - Hello");
this.http.post<any>(this._tokenUrl, user)
.subscribe(
res => {
//getToken_Step2 : SET TOKEN SOMEWHERE
console.log("getToken_Step2 - Token : ", res.token);
},
err => console.log(err)
);
console.log("getToken_Step3 - Bye");
}
setUserData(userName){
console.log("setUserData_Step1 - Hello");
this.http.get<any>(this.getUserInfoUrl+userName)
.subscribe(
res=>{
//setUserData_Step2 : SET USERINFO SOMEWHERE
console.log("setUserData_Step2 - User Info : ", res);
},
err=>{
console.log(err);
}
)
console.log("setUserData_Step3 - Bye");
}
getUserData(){
console.log("getUserData_Step1 - Hello");
return this.userInfo;
}
}
惠康組件
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../../auth.service';
@Component({
selector: 'app-wellcome',
templateUrl: './wellcome.component.html',
styleUrls: ['./wellcome.component.scss'],
})
export class WellcomeComponent implements OnInit {
constructor(private _auth: AuthService){ }
ngOnInit() {
console.log("Wellcome_Step1 - Hello");
let userInfo = this._auth.getUserData();
console.log("Wellcome_Step2 - Show User Info");
}
}
如果您看代碼,會有很多console.log(“ Step .. ,我正在解釋我想通過使用它們來做什么。
簡而言之,我可以說我想按以下順序在控制台屏幕中看到它們:
這些是我想在控制台日志屏幕上看到的步驟,但是我無法以正確的順序看到它們。 我的控制台輸出與我的預期有很大不同。 因為我不知道如何使用angular 5 observable,所以無法處理API返回的值。
我的控制台輸出類似這樣的內容:
- LoginStep_1-您好
- LoginStep_3-SetUserData完成
- getToken_Step1-您好
- getToken_Step2-令牌
...在這里,為什么要這個命令? 我該如何糾正?
所以現在,我該怎么做? 我想通過LoginComponent獲取令牌和用戶信息,並從WellCome組件中使用它們。
就像我說的,我不是一個有經驗的編碼員,所以也許解決方案很簡單但是找不到。
謝謝您的幫助。
由於您對后端的請求是異步的,因此需要花費一些時間來執行。 因此,Angular將繼續執行其他任務: console.log('LoginStep_2 - Token Verified');
和console.log('LoginStep_3 - SetUserData Finished');
在之前getToken()
和setUserData()
完成。
您可以移動訂閱組件
在您的AuthService中
getToken(user){
console.log("getToken_Step1 - Hello");
return this.http.post<any>(this._tokenUrl, user)
// subscribe moves to component
}
在你的組件中
this._auth.getToken(this.loginUserData)
.subscribe(
res => {
//getToken_Step2 : SET TOKEN SOMEWHERE
console.log("getToken_Step2 - Token : ", res.token);
},
err => console.log(err)
)
基本上,您應該實現函數調用以返回promise
或observable
(又稱異步)。 AuthService
如下所示(根據您的問題進行了修改):
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable, of} from 'rxjs';
@Injectable()
export class AuthService {
constructor(private http: HttpClient) {}
// private _tokenUrl = "http://localhost:8000/api/auth/token/";
// This is just a mock URL that returns a response (200 OK)
private _tokenUrl =
"https://bikewise.org:443/api/v2/incidents?page=1&proximity_square=100";
// private getUserInfoUrl = "http://127.0.0.1:8000/api/userInfo/?username=";
private userInfo: any;
// can improve with getter/setter instead of exposing directly
private isLoggedIn: boolean = false;
isLoggedInObservable: Observable<boolean>;
getToken(user): Promise<any> {
console.log("getToken_Step1 - Hello");
return new Promise(resolve => {
// this.http.post<any>(this._tokenUrl, user)
// fake request to make sure always get a response
this.http.get<any>(this._tokenUrl)
.subscribe(
res => {
// getToken_Step2 : SET TOKEN SOMEWHERE
console.log("getToken_Step2 - Token : ", "token_1234");
console.log("getToken_Step3 - Bye");
// resolve(res.token);
resolve("token1234");
},
err => {
console.log(err);
throw new Error('Unauthorized...');
});
})
}
setUserData(userName) {
console.log("setUserData_Step1 - Hello");
// If this is a real request, make sure to implement a promise/observable
// return
// this.http.get<any>(this.getUserInfoUrl + userName)
// setUserData_Step2 : SET USERINFO SOMEWHERE
console.log("setUserData_Step2 - User Info : ");
console.log("setUserData_Step3 - Bye");
this.isLoggedIn = true;
this.isLoggedInObservable = of(true);
}
getUserData() {
console.log("getUserData_Step1 - Hello");
return this.userInfo;
}
logOut() {
this.isLoggedInObservable = of(false);
this.isLoggedIn = false;
}
isLogged(): boolean { return this.isLoggedIn; }
}
您還需要為路由設置AuthGuard
,以跟蹤用戶是否登錄。
這是一個工作示例stackblitz 。 打開控制台以跟蹤狀態
此外,您始終可以將用戶登錄狀態緩存在瀏覽器localStorage
以獲得更好的用戶體驗。 同樣,這是根據您的代碼改編的。 您的代碼有很多可以改進的地方。 如果您還有其他問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.