Angular 10中使用first操作符报错及Login方法返回值问题
first Operator Let's break down your two issues one by one and fix them step by step:
1. Original Error: "Property pipe does not exist on type void"
This error pops up because your initial login method in AuthenticationService doesn't return anything. TypeScript automatically infers the return type as void when no return statement is present, and you can't chain .pipe() onto a void value.
Looking at your initial code: you create an HTTP request Observable with this.http.post(...), but you never send that Observable back from the method. So when you call this.authenticationService.login(...) in your component, you're trying to use .pipe() on a non-Observable value—hence the error.
2. Second Error: Mismatched Return Type After Adding Observable<User>
You correctly added the return type Observable<User> to the login method, but you still didn't return the Observable created by this.http.post(...). TypeScript enforces that the method's actual return value matches the declared type, so this causes a new error because you're still returning void instead of the expected Observable.
Full Corrected Code for AuthenticationService
Here's the fixed login method with two critical fixes, plus a bonus URL cleanup:
- Return the Observable: We add
returnbeforethis.http.post(...)to pass the Observable back to the component - Fix URL concatenation: Your original code was converting
userIdanduserPasswordto strings like"[object Object]"(since you wrapped them in curly braces), which would break your API call. We use template literals for cleaner, error-proof URL building - Add type safety: We use
http.post<User>()to tell TypeScript the response will be aUserobject
import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; // Make sure to import your User interface import { User } from './path-to-your-user-interface'; @Injectable({ providedIn: 'root' }) export class AuthenticationService { private Url = 'your-api-base-url-here'; // Replace with your actual base API URL currentUserSubject: BehaviorSubject<User>; // Assuming this is defined elsewhere in your service constructor(private http: HttpClient) {} login(userId: string, userPassword: string): Observable<User> { // Clean URL construction with template literals const fullApiUrl = `${this.Url}/${userId}/${userPassword}`; // Return the HTTP Observable so the component can chain pipe/subscribe return this.http.post<User>(fullApiUrl, {}) // Add a body here if your API expects one .pipe(map(user => { // Store user details and token in local storage localStorage.setItem('currentUser', JSON.stringify(user)); this.currentUserSubject.next(user); return user; })); } }
Component Code Note
Your component's submitForm method is already correct! Once the login method returns a valid Observable, .pipe(first()) will work exactly as intended—it takes the first emission from the login response and completes the Observable, which is perfect for one-time login requests.
内容的提问来源于stack exchange,提问作者Asad Iftikhar

