MEAN栈应用报错:TypeError: this.listService.addItem(...).subscribe is not a function
TypeError: this.listService.addItem(...).subscribe is not a function Error in Your MEAN Stack App Hey there, let's break down why you're hitting this error and fix it step by step. I've gone through your code, and the main issues are in your list.service.ts file, plus a small oversight in your component initialization.
1. Critical Syntax Error in addItem Method
Your http.post call has a misplaced closing parenthesis that's breaking the method's return value entirely. Look at the broken line:
return this.http.post('http://localhost:3000/todos/dashboard'), newTodo, httpOptions)
The closing ) after the URL is out of place—this means you're not passing newTodo and httpOptions to the post method correctly. Without those arguments, the method doesn't return a valid Observable, so calling .subscribe() on it throws the error you're seeing.
2. Unnecessary res.json() Mapping
When using Angular's modern HttpClient (not the old Http module), the response is automatically parsed as JSON. Adding .map(res => res.json()) is redundant, and it's also using outdated RxJS syntax (pre-6.x). We can remove that mapping entirely.
3. Incorrect Header Creation in getAllTodos
You're using new Headers() instead of new HttpHeaders()—since you're importing HttpHeaders from @angular/common/http, this is a typo that could cause issues with your GET request. Also, you already defined httpOptions at the top of the service, so you can reuse that instead of creating headers manually.
4. Missing Initial List Fetch in ngOnInit
Your DashboardComponent has a getLists() method, but you're not calling it in ngOnInit(). That means your initial list of items won't load when the component starts—something you'll want to fix once the service is working.
Fixed list.service.ts Code
Here's the corrected service with all issues addressed:
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs'; import { List } from '../list'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; @Injectable() export class ListService { constructor(private http: HttpClient) { } getAllTodos(): Observable<List[]> { // Reuse the existing httpOptions instead of creating new headers return this.http.get<List[]>('http://localhost:3000/todos/lists', httpOptions); } addItem(newTodo): Observable<any> { // Fixed parenthesis placement, removed redundant map return this.http.post('http://localhost:3000/todos/dashboard', newTodo, httpOptions); } }
Fixed dashboard.component.ts Initialization
Add a call to getLists() in your ngOnInit to load initial items:
ngOnInit() { this.authService.getProfile().subscribe(profile => { this.user = profile.user; }, err => { console.log(err); return false; }); // Fetch initial list items when the component loads this.getLists(); }
Why This Works
- The corrected
postcall now returns a valid Observable, so.subscribe()will work as expected. - Removing
map(res => res.json())aligns with modernHttpClientbehavior, which handles JSON parsing automatically. - Reusing
httpOptionsensures consistent header configuration across your service methods. - Calling
getLists()inngOnInitpopulates yourlistsarray when the component initializes, so new items will appear alongside existing ones after being added.
Give these changes a try, and your add button should start saving items to MongoDB and displaying them on the page as expected!
内容的提问来源于stack exchange,提问作者Cuong Vo

