Angular中sessionStorage存有用户数据但HTML无法渲染问题求助
Hey there! Let's dig into why your currentUser data isn't rendering correctly in the Angular template even though you've confirmed it exists in sessionStorage. Here are the key steps to diagnose and fix the issue:
1. First, Verify the Raw Session Storage Data
First things first—let's make sure the data stored in sessionStorage is exactly what you expect:
- Open your browser's DevTools (F12), go to the Application tab, and expand Session Storage.
- Look for the
auth-userkey and check its value. Confirm it's a valid JSON string, and that it includes theemployee_codeandaccessTokenfields you're trying to display in the template. If these fields are missing or the JSON is malformed, that's your root cause.
2. Debug the TokenStorageService's Parsing Logic
Your getUser() method might be failing silently when parsing the JSON data. Let's add some logging to catch errors:
public getUser(): any { const user = window.sessionStorage.getItem(USER_KEY); console.log('Raw sessionStorage user data:', user); // Print the raw string if (user) { try { const parsedUser = JSON.parse(user); console.log('Parsed user object:', parsedUser); // Print the parsed object return parsedUser; } catch (e) { console.error('Failed to parse user data:', e); // Catch JSON parsing errors return null; // Return null instead of empty object for better ngIf checks } } return null; }
Check the console for these logs—if parsing fails, you'll see exactly why.
3. Fix the Component's Data Handling
Right now, your component only fetches the user data once on initialization. If the sessionStorage data is set after the component loads (e.g., after logging in and navigating to the home page), the component won't pick up the update. Let's use an observable to make the component react to data changes:
Update TokenStorageService to use a BehaviorSubject
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; const USER_KEY = 'auth-user'; @Injectable({ providedIn: 'root' }) export class TokenStorageService { private userSubject = new BehaviorSubject<any>(this.getStoredUser()); private getStoredUser(): any { const user = window.sessionStorage.getItem(USER_KEY); if (user) { try { return JSON.parse(user); } catch (e) { console.error('Invalid user data:', e); return null; } } return null; } signOut(): void { window.sessionStorage.clear(); this.userSubject.next(null); // Notify subscribers of logout } public saveUser(user: any): void { window.sessionStorage.setItem(USER_KEY, JSON.stringify(user)); this.userSubject.next(user); // Notify subscribers of new user data } public getUserObservable() { return this.userSubject.asObservable(); } public getUser(): any { return this.userSubject.value; } }
Update HomeComponent to subscribe to changes
import { Component, OnInit, OnDestroy } from '@angular/core'; import { TokenStorageService } from '../../../services/token-storage.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.css'] }) export class HomeComponent implements OnInit, OnDestroy { currentUser: any; private userSubscription: Subscription; constructor(private token: TokenStorageService) { } ngOnInit(): void { // Get initial user data this.currentUser = this.token.getUser(); // Subscribe to future changes this.userSubscription = this.token.getUserObservable().subscribe(user => { this.currentUser = user; }); } ngOnDestroy(): void { // Clean up subscription to avoid memory leaks if (this.userSubscription) { this.userSubscription.unsubscribe(); } } }
4. Fix the Template's ngIf Condition
Right now, *ngIf="currentUser" will evaluate to true even if currentUser is an empty object (since empty objects are truthy in JavaScript). To properly show the "Please login" message when there's no valid user, adjust the condition:
<div class="container" *ngIf="currentUser?.employee_code; else loggedOut"> <!-- Your profile content here --> </div> {{ currentUser | json }} <!-- This should now show the correct data --> <ng-template #loggedOut> Please login. </ng-template>
The ?. optional chaining operator ensures we don't throw errors if currentUser is null, and we only show the profile if employee_code exists.
Final Checks
- After making these changes, test logging in again and navigating to the home page.
- Check the console logs to confirm the user data is being parsed correctly and the component is receiving updates.
内容的提问来源于stack exchange,提问作者Kittiphob Rakyutitham

