html - 对几个 URL 端点使用一个请求 - 角度
问题描述
我将解释,我正在尝试将 getProducts(后端控制器)用于网站中的 3 个页面,这些页面使用解析器来显示数据,以下是选项 -
http://localhost:4200/product-list?gender=2&category=4
http://localhost:4200/product-list?gender=2
http://localhost:4200/product-list?category=4
我可以使用相同的控制器吗?我想我可以,但我不知道怎么做。
前端代码 -
html示例-
只有性别——
<a
class="navLink navLink--gender"
click="refreshPage()"
[routerLink]="['/product-list']"
[queryParams]="{ category: 1 }">
Men
</a>
性别和类别 -
<a
class="linkCategoriesInner__link"
click="refreshPage()"
[routerLink]="['/product-list']"
[queryParams]="{ gender: 1, category: 1 }">
Jeans
</a>
路由模块 -
{
path: 'product-list',
component: ProductsComponent,
resolve: { users: ProductsResolver },
}
产品列表组件 -
constructor(private route: ActivatedRoute) {
this.refreshPage();
}
public refreshPage() {
this.route.data.subscribe((data: Data) => {
const products = data['users'] as IProductInterface[];
if (products.length === 0) {
this._noProducts = true;
return;
}
this._noProducts = false;
this._products = products.map((product) => new Product(product));
});
}
产品列表解析器 -
class ProductsResolver implements Resolve<Pick<IProductInterface, 'image' | 'title' | 'price' | 'description'>[]> {
constructor(private productService: ProductService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Pick<
IProductInterface, 'image' | 'title' | 'price' | 'description'>[]> {
return this.productService.getProducts(
+route.queryParamMap.get('gender')! as ProductGender,
+route.queryParamMap.get('category')! as ProductCategory,
);
}
}
产品列表服务 -
public getProducts(
gender?: ProductGender,
category?: ProductCategory
): Observable<IProductInterface[]> {
return this.httpProductService.getProducts(gender, category).pipe(
catchError((errorResponse: HttpErrorResponse) => {
let errorMessage: string;
switch (errorResponse.status) {
case 400:
errorMessage = 'Getting products failed';
break;
default:
errorMessage = 'An error occurred';
}
return throwError(errorMessage);
}),
map((response: IGetProductsResponse) => response.data!)
);
}
产品列表 http 服务 -
public getProducts(
gender?: ProductGender,
category?: ProductCategory
): Observable<IGetProductsResponse> {
const baseUrl = ENDPOINT;
return this.http.get<IGetProductsResponse>(
`${baseUrl + 'list/' + gender}/${category}`
);
}
上面提到IGetProductsResponse
-
export interface IGetProductsResponse extends IResponse {
readonly data?: IProductInterface[];
}
后端代码 -
路由器——
router.get("/list/:gender/:category", getProducts);
控制器 -
const getProducts = async (
req: IgetProductsRequest,
res: IgetProductsResponse
) => {
ServerGlobal.getInstance().logger.info(
`<getProducts>: Start processing request filtered by \
category ${req.params.category} and gender ${req.params.gender}`
);
if (!ServerGlobal.getInstance().isValidCategoryValue(+req.params.category!)) {
ServerGlobal.getInstance().logger.error(
`<getProducts>: Failed to get products because of invalid category filtered by category ${req.params.category} \
and gender ${req.params.gender}`
);
res.status(400).send({
success: false,
message: "Please provide valid category",
});
return;
}
if (
!ServerGlobal.getInstance().isValidGenderValue(+req.params.gender!)
) {
ServerGlobal.getInstance().logger.error(
`<getProducts>: Failed to get products because of invalid gender filtered by category ${req.params.category} \
and gender ${req.params.gender}`
);
res.status(400).send({
success: false,
message: "Please provide valid gender",
});
return;
}
try {
const products = await ProductDB.find({
category: +req.params.category!,
gender: +req.params.gender!,
});
ServerGlobal.getInstance().logger.info(
`<getProducts>: Successfully got the products filtered by \
category ${req.params.category} and gender ${req.params.gender}`
);
res.status(200).send({
success: true,
message: "Successfully retrieved products",
data: products.map((product) => ({
id: product.id as string,
category: {
value: product.category,
label: ServerGlobal.getInstance().getCategoryLabel(product.category)!,
},
gender: {
value: product.gender,
label: ServerGlobal.getInstance().getGenderLabel(product.gender)!,
},
title: product.title,
description: product.description,
price: product.price,
imageFilename: product.imageFilename,
})),
});
return;
} catch (e) {
ServerGlobal.getInstance().logger.error(
`<getProducts>: Failed to get products filtered by \
category ${req.params.category} and gender ${req.params.gender} because of server error: ${e}`
);
res.status(500).send({
success: false,
message: "Server error",
});
return;
}
};
上面提到IgetProductsRequest
-
interface IgetProductsRequest extends express.Request {
readonly params: Readonly<{
gender?: string;
category?: string;
}>;
}
上面提到IgetProductsResponse
-
type IgetProductsResponse = express.Response<
IServerResponse & {
data?: {
id: string;
category: { value: ProductCategory, label: string };
gender: { value: ProductGender, label: string };
title: string;
description: string;
price: number;
imageFilename: string;
}[];
}
>;
解决方案
您发布了很多代码,下次请提供最少的代码来重现问题。
我更改了控制器以检查性别和/或类别,然后在 ProductDB.find() 函数中使用这些值。
更新的控制器
const getProducts = async (
req: IgetProductsRequest,
res: IgetProductsResponse
) => {
ServerGlobal.getInstance().logger.info(
`<getProducts>: Start processing request filtered by \
category ${req.params.category} and gender ${req.params.gender}`
);
if (!req.params.category && !req.params.gender) {
res.status(400).send({
success: false,
message: "Please provide a category and/or gender",
});
return;
}
const dbQueryParams = {};
if (req.params.category) {
if (!ServerGlobal.getInstance().isValidCategoryValue(+req.params.category!)) {
ServerGlobal.getInstance().logger.error(`<getProducts>: Failed to get products because \
of invalid category filtered by category ${req.params.category} \
and gender ${req.params.gender}`);
res.status(400).send({
success: false,
message: "Please provide valid category",
});
return;
}
dbQueryParams.category = +req.params.category!
}
if (req.params.gender) {
if (!ServerGlobal.getInstance().isValidGenderValue(+req.params.gender!) {
ServerGlobal.getInstance().logger.error(`<getProducts>: Failed to get products because \
of invalid gender filtered by category ${req.params.category} \
and gender ${req.params.gender}`);
res.status(400).send({
success: false,
message: "Please provide valid gender",
});
return;
}
dbQueryParams.gender = +req.params.gender!
}
try {
const products = await ProductDB.find(dbQueryParams);
ServerGlobal.getInstance().logger.info(
`<getProducts>: Successfully got the products filtered by \
category ${req.params.category} and gender ${req.params.gender}`
);
res.status(200).send({
success: true,
message: "Successfully retrieved products",
data: products.map((product) => ({
id: product.id as string,
category: {
value: product.category,
label: ServerGlobal.getInstance().getCategoryLabel(product.category)!,
},
gender: {
value: product.gender,
label: ServerGlobal.getInstance().getGenderLabel(product.gender)!,
},
title: product.title,
description: product.description,
price: product.price,
imageFilename: product.imageFilename,
})),
});
return;
} catch (e) {
ServerGlobal.getInstance().logger.error(
`<getProducts>: Failed to get products filtered by \
category ${req.params.category} and gender ${req.params.gender} because of server error: ${e}`
);
res.status(500).send({
success: false,
message: "Server error",
});
return;
}
};
推荐阅读
- excel - 如果条件不正确,则在单元格中“跳过写入”的 Excel 公式
- python-3.x - 谷歌云 - 删除存储桶元数据
- node.js - 在本地开发 Web App 时设置 HttpOnly Cookies
- node.js - 如何使用带有反应功能组件的 API 创建投票
- facebook - Facebook Attribution API by custom source
- sql - BigQuery 中的 DATE_DIFF() 用于计算行之间的时间
- javascript - 如何在不重复的情况下显示随机问题
- upload - Upload audio file to Jodit
- tcp - 重新连接 TCP 发送握手的 Spring 集成
- python - adding an auth check to github webhooks using flask + python3