我将Angular与后端的Restful C#API结合使用。我正在创建一个简单的购物车,并且整天都在努力。当我在页面中调用添加到购物车方法时,逻辑首先检查商品是否已经在购物车中。如果是,它将增加计数并返回乘积,以便状态可以更新。如果产品不在购物车中,则会将产品添加到购物车并返回产品对象以更新状态。
最初的通话出错了,它弄乱了一切-如果您能帮助我弄清楚发生了什么,我将万分感谢!
C#方法
[HttpGet("GetItem/{cartId}/item/{prodId}")]
public async Task<ProductViewModel> GetItem(string cartId, int prodId)
{
var prod = await _shopCartSvc.GetItem(cartId, prodId);
return prod;
}
[HttpGet("CreateItem/{cartId}/item/{prodId}")]
public async Task<ProductViewModel> CreateItem(string cartId, int prodId)
{
var prod = await _shopCartSvc.CreateItem(cartId, prodId);
return prod; // I stop it here to check my return values
}
在角度形式中,产品卡组件具有以下逻辑
addToCart() {
console.log('addToCart');
this.cartSvc.addToCart(this.product)
.subscribe((p : Product) => {
this.product = p;
console.log('addToCart.done',p);
});
}
这将调用购物车服务addToCart公共方法
addToCart(product: Product) {
console.log('cs.addToCart');
return this.updateItem(product);
}
这又调用了私有的updateItem方法来进行所有处理
private getItem(cartId: string, productId: number) {
console.log('getItem-productId', productId);
return this.http.get(this.getBaseUrl() + 'GetItem/'+ cartId +'/item/' + productId)
.pipe(
map((response: Product) => {
console.log('getItem-done', response);
return response
}),
catchError(this.handleError));
}
private createItem(cartId: string, productId: number) {
console.log('createItem');
return this.http.get(this.getBaseUrl() + 'CreateItem/'+ cartId + '/item/' + productId)
.pipe(
map((response: Product) => {
console.log('createItem-done', response);
return response
}),
catchError(this.handleError));
}
private updateItem(product: Product, amt: number = 1): Observable<Product> {
let cartId = this.getOrCreateCartId();
return this.getItem(cartId, product.id)
.switchMap(item => {
if (item == null) {
console.log('addItem');
// Create new item in cart
this.createItem(cartId, product.id)
.subscribe(item => {
console.log('addItem.done',item);
return of(item);
});
} else {
let total = item['quantity'] + amt;
if (total > 0) {
// Update qty of existing item in cart
item['quantity'] = total;
console.log('Cart Id',cartId,', UpdateItemQty to', total);
this.http.post(this.getBaseUrl() + 'UpdateItem/'+ cartId, item)
.take(1).switchMap( item => {
console.log('UpdateItem.done - newQty', item['quantity']);
return of(item);
});
} else {
// Qty 0 so remove
console.log('DELETE');
this.http.get(this.getBaseUrl() + 'RemoveItem/'+ cartId + '/item/' + item['id']);
return of (product);
} // end if
} // end if
}); // getItem - switchMap
}
在最初将商品添加到购物车期间会发生什么,因为它抛出一个错误,但仍在添加商品。遵循日志消息,我得到
console.js:35 cs.addToCart
console.js:35 getItem-productId 1
console.js:35 getItem-done null
console.js:35 addItem
console.js:35 createItem
console.js:35 Global - Unhandled Error: TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
....
console.js:35 createItem-done {name: "Beagle", description: "", imageUrl: "Beagle.png", defaultTextColor: "Black", isPremiumProduct: false, …}
console.js:35 addItem.done {name: "Beagle", description: "", imageUrl: "Beagle.png", defaultTextColor: "Black", isPremiumProduct: false, …}
我是Angular的新手,我一生无法弄清问题所在。我可以进入C#后端并将其停在return语句上,以查看返回的值。这是正确的类型和正确的值。当我在后端时发生错误,当我继续执行流时,它将完成,但是由于该错误,我的对象状态不会更新。我得到的完整错误是:
console.js:35 Global - Unhandled Error: TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeTo (subscribeTo.js:41)
at subscribeToResult (subscribeToResult.js:11)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:51)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._next (switchMap.js:41)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at CatchSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)
at CatchSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterSubscriber._next (filter.js:38)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:84)
at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:15)
at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at XMLHttpRequest.onLoad (http.js:1534)
at XMLHttpRequest.wrapped (raven.js:376)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:14051)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
at invokeTask (zone.js:1744)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1781)
答案 0 :(得分:1)
这里:
if (item == null) {
console.log('addItem');
// Create new item in cart
this.createItem(cartId, product.id)
.subscribe(item => {
console.log('addItem.done',item);
return of(item);
});
}
创建该项目是因为您具有API调用和订阅,但是没有return语句。订阅中的内容不算在内。如果您想返回流并产生一些副作用,则应该
if (item == null) {
console.log('addItem');
// Create new item in cart
return this.createItem(cartId, product.id)
.pipe(tap(item => {
console.log('addItem.done',item);
}))
}