【问题标题】:Angular doesn't write the value after updating sessionStorageAngular 在更新 sessionStorage 后不写入值
【发布时间】:2023-01-07 01:32:14
【问题描述】:

我的代码很简单,我的组件中有这个 html

<h2>{{username}}</h2>
<h2>{{sessionId}}</h2>

这是我用来更新这些变量的脚本


    //i check for when the router redirects to the /user component
    router.events.pipe(
      filter((e: Event): e is RouterEvent => e instanceof RouterEvent)
    ).subscribe(() => {
      //router event happens
      if (location.path() == "/user") {
        //I do a call to the backend to get the user info I need
        let userTemp = <string>sessionStorage.getItem("username");
        const params = new HttpParams()
          .set('username', userTemp);
        //the call happens in the service calss that I inject
        this.service.getUserInfo(params);
        //all it does is getting the data and sessionStorage.setItem() on both values
        this.username = <string>sessionStorage.getItem("username");
        this.sessionId = <string>sessionStorage.getItem("sessionId");
      }
    });

即使我先设置值然后获取它们,html 中也只显示用户名变量,不会在 &lt;h2&gt;&lt;/h2&gt; 标记之间绘制 sessionId 变量。这可能是因为我在 sessionStorage 中已经有了“用户名”值。 注意:两个变量在类中都设置为“null”

这是服务:

getUserInfo(params: HttpParams) {
    this.http.get<UserData>('/api/getuserinfo', { params, responseType: 'json' }).subscribe(response => {
      //I set the username again
      sessionStorage.setItem("username", response.username);
      //I add a new value called sessionId
      sessionStorage.setItem("sessionId", response.sessionId);
    });
  }

我尝试设置 ngOnInit() 函数以设置初始化值,然后在服务调用后调用 this.ngOnInit() 但即使调用该函数也是如此。代码上的任何变化都没有帮助,而且我没有找到任何可以解释为什么 Angular 看不到变量更新的内容,即使我可以从调试器访问 sessionStorage 对象中的值。

【问题讨论】:

    标签: angular angular-services angular-router session-storage


    【解决方案1】:

    您拥有的是因为 Javascript 引擎执行每个函数的时间。

    查看您的代码,您有一个可观察的“router.events”,它在其订阅中执行几项操作。直到这里一切都很好。然而,问题发生在订阅内,更准确地说,是在执行对您的服务的调用时。

    subscribe(() => {
      if (location.path() == "/user") {
        let userTemp = <string>sessionStorage.getItem("username");
        const params = new HttpParams().set('username', userTemp);
        
        this.service.getUserInfo(params); // <- Here is the issue.
        
        this.username = <string>sessionStorage.getItem("username");
        this.sessionId = <string>sessionStorage.getItem("sessionId");
      }
    })
    

    javascript执行这段代码时,顺序如下:

    1. 进入if块;
    2. 尝试从sessionStorage获取"username"并将其分配给userTemp
    3. 创建 params HttpParams 实例并设置所提供属性的值。
    4. 呼叫getUserInfo(params)。此方法创建并可观察并订阅它。
    5. 尝试从sessionStorage获取"username"并将其分配给this.username
    6. 尝试从sessionStorage获取"sessionId"并将其分配给sessionId
    7. 解析getUserInfo(params)subscribe 中的代码,它设置sessionStorage 中的值。

      如您所见,问题在于您希望第 7 步在第 5 步和第 6 步之前执行。

      为此,您要么需要依赖可观察运算符(这更复杂),要么需要将 this.service.getUserInfo(params) 的返回值转换为 Promise 并等待其解决。

      如果要将其转换为Promise,最简单的方法如下:

      getUserInfo(params: HttpParams): Promise<void> {
        this.http.get<UserData>('/api/getuserinfo', { params, responseType: 'json' })
          .pipe(tap(response => {
            sessionStorage.setItem("username", response.username);
            sessionStorage.setItem("sessionId", response.sessionId);
          })).toPromise();
      }
      

      在您的订阅中,您还需要将其修改为异步,如下所示:

      subscribe(async () => {  // Add async here
        if (location.path() == "/user") {
          let userTemp = <string>sessionStorage.getItem("username");
          const params = new HttpParams().set('username', userTemp);
          
          await this.service.getUserInfo(params); // Await the resolution of the api call
          
          this.username = <string>sessionStorage.getItem("username");
          this.sessionId = <string>sessionStorage.getItem("sessionId");
        }
      })
      
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多