Angular In-memory-web-api获取单个对象时抛出404错误求助
解决Angular in-memory-web-api获取单个Podcast时的404错误
嘿,我之前也踩过这个坑!in-memory-web-api默认是通过id字段来匹配单个资源的,而你现在用name作为路由参数来查询,它根本识别不了这个匹配规则,所以才会返回404。下面给你几个实用的解决办法,你可以根据自己的场景选:
方法一:自定义InMemoryDataService的请求处理
你可以在InMemoryDataService里重写get方法,专门处理基于name的查询请求。这样不管是路径参数还是其他规则,都能自己控制:
import { InMemoryDbService, RequestInfo } from 'angular-in-memory-web-api'; import { Podcast } from './podcast'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class InMemoryDataService implements InMemoryDbService { createDb() { const podcasts = [ { id: 1, name: 'angular-tips', title: 'Angular入门技巧' }, { id: 2, name: 'rxjs-deep-dive', title: 'RxJS深度解析' } ]; return { podcasts }; } // 重写get方法,处理按name匹配的请求 get(reqInfo: RequestInfo) { // 匹配 /podcasts/xxx 这样的路径 const nameMatch = reqInfo.url.match(/\/podcasts\/([^\/]+)$/); if (nameMatch) { const targetName = nameMatch[1]; const podcasts = reqInfo.collection as Podcast[]; const matchedPodcast = podcasts.find(podcast => podcast.name === targetName); if (matchedPodcast) { // 返回找到的资源 return reqInfo.utils.createResponse$(() => ({ body: matchedPodcast, status: 200 })); } else { // 没找到的话返回404(这步可选,也可以返回空) return reqInfo.utils.createResponse$(() => ({ body: { error: 'Podcast不存在' }, status: 404 })); } } // 其他请求交给默认逻辑处理 return undefined; } }
方法二:改用查询参数来请求
如果不想改内存服务的逻辑,也可以调整你的podcast-service,用查询参数传递name,in-memory-web-api会自动帮你过滤:
// podcast.service.ts getPodcast(name: string): Observable<Podcast> { // 用?name=xxx的形式传递参数 const requestUrl = `${this.podcastsBaseUrl}?name=${name}`; return this.http.get<Podcast[]>(requestUrl).pipe( // 因为返回的是匹配的数组,取第一个元素就行 map(podcasts => podcasts[0]) ); }
这种方式不用改内存服务,简单直接,适合快速调试。
方法三:把name设为资源的id字段
如果你的Podcast的name是唯一的(不会重复),那最简单的办法就是把id字段直接设为name的值,这样in-memory-web-api的默认匹配规则就生效了:
// InMemoryDataService里的模拟数据 const podcasts = [ { id: 'angular-tips', name: 'angular-tips', title: 'Angular入门技巧' }, { id: 'rxjs-deep-dive', name: 'rxjs-deep-dive', title: 'RxJS深度解析' } ];
然后你的服务请求代码不用改,还是原来的:
getPodcast(name: string): Observable<Podcast> { const url = `${this.podcastsBaseUrl}/${name}`; return this.http.get<Podcast>(url); }
这样in-memory-web-api会把路径里的name当成id去匹配,自然就能找到对应的Podcast了。
最后别忘了检查一下组件里传递的name参数是不是正确,比如路由里的:name有没有正确传递到组件的getPodcast方法里哦!
内容的提问来源于stack exchange,提问作者Tom O'Brien
相关产品推荐
相关产品推荐

