Ember.js 5.4 how to update component variable when session store is updated

20 views Asked by At

Ember.js Octane and JavaScript (not TS)

I have a service to access the session store. When I add or remove a specific key, I want my top level component to toggle visibility for the nav-bar. I have tried variations of tracking, etc. I attempted to get an observer working, but frankly, I don't understand it, and I'm not sure if that's what I need.

When the store is updated, and then I manually press F5, the application shell then sees the change.

When I call setAuthenticationToken(value), I want the applcaiton-shell to notice the change.

How do I make it so that the application-shell sees the change on its own?


application-shell .hbs & .js

{{#if this.isAuthenticated}}
<nav class="mt-8">...</nav>
{{/if}

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking'
import { inject as service } from '@ember/service';

export default class ApplicationShellComponent extends Component {
    @service SessionManager
    @tracked isAuthenticated = this.SessionManager.isAuthenticated
}

service.js

const SessionId_Key = 'SIDK'
export default class SessionManagerService extends Service {

    @tracked isAuthenticated = this.getAuthenticationToken()
    
    delAuthenticationToken()     {        this.delItem(SessionId_Key)        }
    getAuthenticationToken()     { return this.getItem(SessionId_Key)        }
    setAuthenticationToken(value){        this.setItem(SessionId_Key, value) }

    delItem(key)        {        sessionStorage.clear  (key)        }
    getItem(key)        { return sessionStorage.getItem(key)        }
    setItem(key, value) {        sessionStorage.setItem(key, value) }
}

Updated with answer: Simply setting the isAuthenticated in the del/set Authentication methods is what I needed.

delAuthenticationToken() {        
  this.delItem(SessionId_Key);
  this.isAuthenticated = false;      
}

setAuthenticationToken(value) {
    this.setItem(SessionId_Key, value);
    this.isAuthenticated = true;
}
1

There are 1 answers

3
NullVoxPopuli On BEST ANSWER

isAuthenticated is only set once

    @tracked isAuthenticated = this.SessionManager.isAuthenticated

this means, the variable isAuthenticated is initialized with the value from sessionManager (not that isAuthenticated always prepresents the value on the right side of = (as assignments only happen once)).

to make it reactive, you'll want to convert it a gatter.

get isAuthenticated() {
  return this.SessionManager.isAuthenticated;
}

otherwise, if you want to keep @tracked isAuthenticated, one of your functions will need to set the value.

In either case, your template

{{#if this.isAuthenticated}}
  <nav class="mt-8">...</nav>
{{/if}

would then update as expected


Your overall code would look like this:

application shell hbs

{{#if this.isAuthenticated}}
  <nav class="mt-8">...</nav>
{{/if}

application shell js


import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking'
import { inject as service } from '@ember/service';

export default class ApplicationShellComponent extends Component {
    @service SessionManager

    get isAuthenticated() {
        return this.SessionManager.isAuthenticated;
    }
}

service:

const SessionId_Key = 'SIDK'
export default class SessionManagerService extends Service {

    @tracked isAuthenticated = this.getAuthenticationToken()
    
    delAuthenticationToken() {        
      this.delItem(SessionId_Key);
      this.isAuthenticated = false;      
    }
    
    getAuthenticationToken() { 
        return this.getItem(SessionId_Key);
    }

    setAuthenticationToken(value) {
        this.setItem(SessionId_Key, value);
        this.isAuthenticated = true;
    }

    delItem(key)        {
        sessionStorage.clear(key);        
    }

    getItem(key)        { 
        return sessionStorage.getItem(key);        
    }
    setItem(key, value) {        
        sessionStorage.setItem(key, value);
    }
}