Maintain generated token for service on injection

Luillyfe

I am creating a service to generate a random token and pass it to a request (In developers Spotify they strongly recommend you to do so). There is a query parameter (state)!

This is my Service:

import { Injectable } from '@angular/core';

@Injectable()
export class TokenService {
    private _state: string;

    constructor() {
        alert('Token got created');
    }

    public get state(): string {
        return this._state;
    }

    generateToken() {
        this._state = this.randomString() + this.randomString();
        alert(this._state);
    }

    private randomString() {
        return Math.random().toString(36).substring(2);
    }
}

And I am calling it here:

...
@Injectable()
export class AngularSpotifyService { 
...
constructor(private windowRef: WindowService, private token: TokenService) { }

getToken(windowName = this.name, windowOptions = this.getOptions()) {
    this.windowRef.nativeWindow.open(`https://accounts.spotify.com/authorize?${this.toQueryString()}`,
      windowName, windowOptions);
}

private toQueryString(): string {
    this.token.generateToken();
    return `client_id=${this.clientId}&response_type=${this.responseType}&redirect_uri=${this.redirectUri}&state=${this.token.state}`;
}

The two services are getting created twice, when launch the app and when the response from spotify arrived.

Expected behaviour: I am generating a random string to fill the state query parameter. When the response arrived I am expecting that the token service not to get created again(I supposed is the normal behaviour) because if so, it is going to generate a new random string and then, the state query parameter (that is returned again with the Spotify response) are not longer equal.

This is my app.module:

...
@NgModule({
  declarations: [
      AppComponent,
      TokenComponent,
      AngularSpotifyComponent
  ],
  imports: [
      BrowserModule,
      RouterModule.forRoot(appRoutes)
  ],
  providers: [WindowService, AngularSpotifyService, TokenService],
  exports: [ RouterModule ],
  bootstrap: [AppComponent]
})
export class SpotifyModule { }
Zze

You can do this via static properties ("object initializers") in your class / service. I made this plunkr to demonstrate.

But the crux of it is that the variable declaration is done outside of the constructor and is computed during the "spin up" time of the class thus instantiating it multiple times does not impact the value.

export class Example{
  static value: string = Math.random().toString(36).substring(2);

  constructor(){
    console.log(Example.value);
  }

  public getValue(){
    return Example.value;
  }
}

this.example1 = new Example();
this.example2 = new Example();


// NOW!
this.example1.getValue() == this.example2.getValue()

So just to clarify the point I am making...

Replace private _state: string; with the class above, and then use example.getValue() wherever you were using _state previously.

So the new service will look like:

@Injectable()
export class TokenService {
    private example: Example;

    constructor() {
        this.example = new Example();
        alert('Token got created');
    }

    public get state(): string {
        return this.example.getValue();
    }

}

Obviously you would probably rename the Example class to whatever you find appropriate.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

HotTag

Archive