更新
问题似乎是map函数不是在"失败"的请求上运行.这意味着如果我正在谈论的API返回422 Validation Failed错误(或其他4xx错误),Angular会将此视为失败并导致Observer运行订阅的错误回调,跳过该过程中的map函数.
是否有可能强制Angular将某些4xx错误视为成功请求,或强制映射函数即使在Observable返回错误时也能运行?
我在Angular2应用程序中运行以下代码:
import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Rx";
import {Http, Headers, ResponseOptions, Response} from "angular2/http";
import 'rxjs/add/operator/map';
...
public login (email : string, password : string) {
return this.http.post(_endPoint + '/auth/login/', JSON.stringify({
email: email,
password: password
}), {
headers: new Headers({
'Content-Type': 'application/json'
})
})
.map (res => {
let data = res.json();
console.log(data);
return data;
});
}
Run Code Online (Sandbox Code Playgroud)
代码执行正常,但不触发map函数.我没有收到任何错误,并尝试使用和不import 'rxjs/add/operator/map'使用相同的结果运行代码.我也尝试过一个更简单的地图功能.map (res => res.json());.
在这两种情况下,我都希望.subscribe()函数中返回的结果是JSON响应,但我得到的是原始响应.
编辑:添加了请求数据和响应的屏幕截图 …
//In services.ts
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import 'rxjs/Rx';
@Injectable()
export class DataService {
constructor(private http: Http) { }
fetch(){
return this.http.get('json-object-link').map(
(res) => res.json()
)
}
}
//In component
ngOnInit() {
this.dataService.fetch()
.subscribe(
(data) => this.ninjas = data
);
}
Run Code Online (Sandbox Code Playgroud)
我想在此请求中添加以下标头:
"headers":
{
"content-type":"application/json",
"access_token":"abcd"
}
对于JWT身份验证,我现在发出一个post请求,以使用Http与Observables一起使用的新模块来获取令牌.
我有一个Login显示表单的简单组件:
@Component({
selector: 'my-login',
template: `<form (submit)="submitForm($event)">
<input [(ngModel)]="cred.username" type="text" required autofocus>
<input [(ngModel)]="cred.password" type="password" required>
<button type="submit">Connexion</button>
</form>`
})
export class LoginComponent {
private cred: CredentialsModel = new CredentialsModel();
constructor(public auth: Auth) {}
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个Auth提出要求的服务:
@Injectable()
export class Auth {
constructor(public http: Http) {}
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
.map(res => res.json())
.subscribe(
data => this._saveJwt(data.id_token),
err …Run Code Online (Sandbox Code Playgroud) 我收到以下错误:
angular2.dev.js:23925 EXCEPTION: TypeError: Cannot read property 'Id' of null in [
{{ product.Id }}
in ProductEditComponent@0:68]
Run Code Online (Sandbox Code Playgroud)
抛出:
//Product-edit.component.ts:
import {Component } from 'angular2/core';
import { IProduct } from './product'
import { ProductService } from './product.service'
import { RouteParams } from 'angular2/router';
@Component({
template:`<div class="wrapper wrapper-content animated fadeInRight ecommerce">
{{ product.Id }}
</div>`,
})
export class ProductEditComponent{
product: IProduct = null;
errorMessage: string;
constructor(private _routeParams: RouteParams, private _productService: ProductService){
}
ngOnInit(): void {
this._productService.getProduct(this._routeParams.get('id'))
.subscribe(
product => this.product = product, …Run Code Online (Sandbox Code Playgroud) 要知道请求是否已完成,我会这样做if (httpEvent instanceof HttpResponse)。同样,如何知道请求是否在 中被取消HttpInterceptor?下面是我的intercept功能。
intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler): Observable<HttpEvent<any>> {
this.requestsPending++;
if (this.typeAheads.includes(httpRequest.url.split('/').pop()))
this.slimLoadingBarService.start();
else
this.flsLoaderService.start();
return httpHandler.handle(httpRequest)
.do((httpEvent: HttpEvent<any>) => {
if (httpEvent instanceof HttpResponse) {
// decrementing counter on each request return
this.requestsPending--;
if (this.typeAheads.includes(httpEvent.url.split('/').pop())) {
if (this.requestsPending === 0)
this.slimLoadingBarService.complete();
}
else {
if (this.requestsPending === 0)
this.flsLoaderService.stop();
}
}
}, () => {
this.slimLoadingBarService.complete();
// reset counter on error
this.requestsPending = 0;
this.flsLoaderService.stop();
});
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试测试 HTTP 调用并参考以下页面来编写单元测试:https://angular-2-training-book.rangle.io/handout/testing/services/mockbackend.html
但是当我查看 Angular 网站时,该类似乎MockBackend已被弃用:https://angular.io/api/http/testing/MockBackend
同一网站有不同的方法来测试 HTTP 调用:https://angular-2-training-book.rangle.io/handout/testing/services/alt-http-mocking.html
我还发现了下面一篇有趣的文章(因为我正在尝试测试登录,因此进行 POST 调用):http://jasonwatmore.com/post/2016/11/24/angular-2-mockbackend-example-for-backendless -发展
所以我想知道测试 HTTP 调用的最佳或最新方法是什么?我有点困惑是否使用MockBackend或使用spyOn模拟策略。
unit-testing angular2-services angular2-http angular2-testing angular
我可以通过以下方式将JSON请求数据发布到服务器,但是如何使用http将XML结构化数据发布到服务器.
getAuthSeed(value) {
let params = "{'validateUsr': 'false'}";
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('params', params);
let url = 'tab-api/login/'+value.username+'/seed/false';
let options = new RequestOptions({
method: RequestMethod.Get,
url: url,
headers: headers
});
return this.http.request(new Request(options)).map(
result => {
let data = result.json();
return data;
}
)
}
Run Code Online (Sandbox Code Playgroud)
示例XML请求:
<pi:ReqPay xmlns:pi="http:schema/">
<Head ver="1.0" ts="" orgId="" msgId=""/>
<Meta>
<Tag name="PAYRE" value=""/>
</Meta>
<Txn id="" note="" custRef="" refId="" refUrl="" ts="" type="PAY|COLLECT">
<RiskScores>
<Score provider="ci" type="TXNRISK" value=""/>
</RiskScores>
<Rules>
<Rule name="MINAMOUNT" value=""/>
</Rules> …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个在类顶部使用API的Angular2 HTTP类.主要的是我需要添加自定义的auth标头,在用户授权后可用.
主要问题是令牌存储在Ionic Storage模块中,只能异步获取,但我需要返回特定的类型....
export class APIRequest extends Http {
private storage : Storage;
constructor (backend: XHRBackend, options: RequestOptions) {
super(backend, options);
this.storage = new Storage;
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
if (typeof url === 'string') {
url = AppConfig.API_SERVER + url
} else {
url.url = AppConfig.API_SERVER + url.url
}
this.storage.get('authToken').then(token => {
if (typeof url === 'string') {
if (!options) {
options = {headers: new Headers()};
}
options.headers.set('Authorization', `Bearer ${token}`);
} else {
url.headers.set('Authorization', …Run Code Online (Sandbox Code Playgroud) 在我的 Angular2 应用程序中,我从 REST API 获取响应并操作它们以便在用户界面中显示它们。
我根据以下教程编写了我的应用程序。
这是我从服务器获取响应的方法
getTendersByCategory(categoryName: string){
console.log("get tenders by category "+categoryName);
let tendersByCategory = this._http
.get(this._endpointUrl + "tender/get-by-category-name/" + categoryName)
.map(mapTenders)
.catch(handleError);
return tendersByCategory;
}
Run Code Online (Sandbox Code Playgroud)
以下函数用于操作响应
function mapTenders(response: Response): Tender[] {
console.log('tender.service.ts -> mapTenders');
/*if(response.status == 204){
console.log("response = 204 - No content in response");
return null;
}*/
return response.json().map(toTender);
}
function toTender(r: any): Tender {
console.log('tender.service.ts -> toTender');
let tender = <Tender>({
id: r.id,
name: r.name,
publisher: r.publisher,
});
return tender;
}
function handleError(error: …Run Code Online (Sandbox Code Playgroud) angular2-services angular2-http angular2-observables angular
我提供CookieXSRFStrategy了XSRFStrategy 在app.module.ts
providers: [
{ provide: APP_BASE_HREF, useValue: '/order/' },
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken') },
{ provide: RequestOptions, useClass: DefaultRequestOptions }
],
Run Code Online (Sandbox Code Playgroud)
在第二次构建时使用watch/serve工作正常,但在使用--prod标志构建时,收到此错误:
ERROR in Error遇到静态解析符号值.不支持函数调用.考虑使用对导出函数的引用替换函数或lambda(原始.ts文件中的位置50:34),解析E中的符号AppModule:/repo/src/app/app.module.ts
ng --version
@angular/cli: 1.0.0
node: 6.9.1
os: win32 x64
@angular/common: 4.0.0
@angular/compiler: 4.0.0
@angular/core: 4.0.0
@angular/forms: 4.0.0
@angular/http: 4.0.0
@angular/platform-browser: 4.0.0
@angular/platform-browser-dynamic: 4.0.0
@angular/router: 4.0.0
@angular/animations: 4.0.0
@angular/cli: 1.0.0
@angular/compiler-cli: 4.0.0
Run Code Online (Sandbox Code Playgroud) angular ×10
angular2-http ×10
ionic2 ×2
observable ×2
typescript ×2
ajax ×1
javascript ×1
rxjs ×1
rxjs5 ×1
unit-testing ×1