1
votes

I'm using a Static variable in my Class to store an initialised BehaviourSubject, so that I can provide a default, while I load the user's settings from the server.

(have put a cut down example version below)

@Injectable
export class AppSettings {
   // Using a static to globalize our variable to get 
   // around different instances making lots of requests.
   static readonly currency: Subject<string> = new BehaviorSubject('USD');

   // Return a property for general consumption, but using
   // a global/static variable to ensure we only call once. 
   get currency(): Observable<string> { return AppSettings.currency; }


   loadFromServer():any {
      // Broadcast the currency once we get back 
      // our settings data from the server.
      this.someService.getSettings().subscribe(settings => {
         // this is called lastly, but AppSettings.currency.observers
         // seems to show as an empty array in the Inspector?? 
         AppSettings.currency.next(settings.currency);
      });
   }
}

When I subscribe to it later in my code, it will run through it once (since it's a BehaviorSubject), but it won't fire after that.

export class myComponent {
   public currency: string;

   constructor(settings: AppSettings) {
       // Called once with the default 'USD'
       settings.currency.subscribe(currency => {
           // only gets here once, before loadFromServer
           console.log(currency);
           this.currency = currency;
       });

       // Load from the server and have our subscription
       // update our Currency property.
       settings.loadFromServer();
   }
}

The loadFromServer() is working exactly as expected, and the AppSettings.currency.next(settings.currency) line is being called, and after the first event. What is interesting however, is at this point, the AppSettings.currency.observables[] is empty, when it was previously filled in.

My thoughts we're initially an issue of different instances, but I'm using a static variable (have even tried a global one) to avoid different instances.

This is the current workflow...

  1. myComponent.constructor subscribes
  2. that subscription fires, giving the default 'USD'
  3. the server data is loaded, and AppSettings.currency.next(settings.currency) is called
  4. ...then...nothing....

I'm expecting that at part 4 the Observer that subscribed in part 1 would be fired again, but it isn't, making my glorified Observer a constant. :(

Am I missing something?

1
is there a typo? I see setting.loadFromServer. shouldn't it be settings. ? - Dhananjai Pai
that was a typo, but the example is a summarized version of my code anyway, as I just wrote an abridged version on the fly. - Guy Park

1 Answers

0
votes

Well I feel sheepish....

Figured out the issue was due to my import statement having the (wrong) file suffix on the file reference. So, in the myComponent file I had...

import { AppSettings } from './settings.js';

While everywhere else I have been using (the correct)

import { AppSettings } from './settings';

which was causing WebPack to compiling two versions of the class, the TypeScript and the (compiled) Javascript version, thus creating two different instances. I managed to see an AppSettings_1 somewhere, that lead me down the rabbit hole to finally gave it away.