Angular 9中如何映射嵌套JSON响应提取Token
Question
I'm an Angular 9 beginner. I have a registration page that sends user info to a Node.js backend, and I get a JSON response structured like this:
{"data": { "_id": "", "permissionLevel": 4, "guestUser": null, "user": { "resetPasswordToken": null, "userPaymentOptions": [], "_id": "", "email": "", "password": "", "displayName": "", "phoneNumber": "", "permissionLevel": 4, "createdDate": "", "__v": 0 }, "token": "", "__v": 0}, "message": "Registered user is successfully created.","meta": {},"error": null}
I've already fetched this response in my Angular code, but I only need to extract the token from this nested object. Here's my current Angular code—can someone help me fix this?
register(email, displayName, password, phoneNumber){ return this.http.post(this.BASE_URL + '/users/register', {email, displayName, password, phoneNumber}) .pipe(map(user => { // store user token in local storage localStorage.setItem('currentRegisteredUser', JSON.stringify(user)); console.log(user); this.currentRegisteredUserSubject.next(user); return user; })); }
Answer
Hey there! Let's break this down simply so you can grab that nested token easily.
First, looking at your API response, the token lives under the data object—so you can access it directly with response.data.token. To make this cleaner (and take advantage of TypeScript's type safety, which is a huge win), let's add some interfaces first to define the response structure. This will prevent typos and give you IDE autocompletion.
Step 1: Define TypeScript Interfaces
Add these interfaces somewhere in your service file (or a separate types file):
// Interface for the inner user object interface RegisteredUser { resetPasswordToken: string | null; userPaymentOptions: []; _id: string; email: string; password: string; displayName: string; phoneNumber: string; permissionLevel: number; createdDate: string; __v: number; } // Interface for the data portion of the response interface RegistrationResponseData { _id: string; permissionLevel: number; guestUser: null; user: RegisteredUser; token: string; __v: number; } // Full registration response interface interface RegistrationApiResponse { data: RegistrationResponseData; message: string; meta: {}; error: null; }
Step 2: Update Your Registration Method
Now modify your register method to use this interface, extract the token, and handle storage properly:
register(email: string, displayName: string, password: string, phoneNumber: string){ // Specify the response type in http.post for type safety return this.http.post<RegistrationApiResponse>(this.BASE_URL + '/users/register', {email, displayName, password, phoneNumber}) .pipe(map(response => { // Extract the nested token const authToken = response.data.token; // Store the token separately (easier for future API requests) localStorage.setItem('authToken', authToken); // If you still need the user data, store the entire data object instead of the full response localStorage.setItem('currentRegisteredUser', JSON.stringify(response.data)); console.log('Extracted token:', authToken); // Update your subject with the relevant user data this.currentRegisteredUserSubject.next(response.data); // Return whatever your component needs—either the token or the full data object return response.data; })); }
Quick Fix (No Interfaces, Not Recommended)
If you want a quick fix without adding interfaces (though I strongly suggest using them for long-term maintainability), you can cast the response to any and access the token directly:
register(email, displayName, password, phoneNumber){ return this.http.post(this.BASE_URL + '/users/register', {email, displayName, password, phoneNumber}) .pipe(map((user: any) => { const authToken = user.data.token; localStorage.setItem('authToken', authToken); localStorage.setItem('currentRegisteredUser', JSON.stringify(user.data)); console.log('Extracted token:', authToken); this.currentRegisteredUserSubject.next(user.data); return user.data; })); }
The key takeaway is that your token is nested one level deep under data, so a simple chain access will get you exactly what you need!
内容的提问来源于stack exchange,提问作者Sahan Thilakarathna

