Stephen Romero
Stephen Romero

Reputation: 3032

How to fetch Auth Token from Selector via NgRx

I've used a template front-end to learn more about Angular State and NgRx and I'm trying to figure out how to retrieve the authentication token stored in the Auth State.

auth.selector.ts

export const currentAuthToken = createSelector(
    selectAuthState,
    auth => auth.authToken
);

auth.reducers.ts

// Actions
import { AuthActions, AuthActionTypes } from '../_actions/auth.actions';
// Models
import { User } from '../_models/user.model';

export interface AuthState {
    loggedIn: boolean;
    authToken: string;
    user: User;
    isUserLoaded: boolean;
}

export const initialAuthState: AuthState = {
    loggedIn: false,
    authToken: undefined,
    user: undefined,
    isUserLoaded: false
};

export function authReducer(state = initialAuthState, action: AuthActions): AuthState {
    switch (action.type) {
        case AuthActionTypes.Login: {
            const _token: string = action.payload.authToken;
            console.log("Token- "+_token); //The token shows up here fine
            return {
                loggedIn: true,
                authToken: _token,
                user: undefined,
                isUserLoaded: false
            };
        }

        default:
            return state;
    }
}

Now I'm trying to call the selector since it is grabbing a slice of the User object, but I can't seem to grab the string of the authToken.

auth.service.ts

import { AuthState } from '../_reducers/auth.reducers'; // Grabs Reducer for Auth
import { currentAuthToken } from '../_selectors/auth.selectors';
import { Store, select } from '@ngrx/store';

@Injectable()
export class AuthService {

			authToken$: Observable<string>;
			constructor(private http: HttpClient, private store: Store<AuthState> ) {

			}
      
      getUserByToken(): Observable<User> {

    			this.authToken$ = this.store.pipe(select(currentAuthToken));
				   console.log(this.authToken$);//This grabs the Store object instead.

				const httpHeaders = new HttpHeaders();

				httpHeaders.append('Authorization', 'Bearer ' + this.authToken$);
				httpHeaders.append('Content-Type', 'application/json');
				return this.http.get<User>(API_USERS_URL, { headers: httpHeaders });
			}
   }

I've tried different ways of grabbing the token, but it seems that the selector is the best way to do it. Of course I'm having trouble. Any help is appreciated.

Upvotes: 0

Views: 805

Answers (1)

Andrei
Andrei

Reputation: 12196

ngRx is build to force usage of "up to date" data through subscribtions. this.authToken$ will not be the token, but an observable that will give you token. Method that will get user by token could look like this

this.store.pipe(
  select(currentAuthToken),
  take(1) // only if you need one time call rather than a call every time token is updated in ngrx
  switchMap(token => { // in this callback token will be string
    const httpHeaders = new HttpHeaders();

    httpHeaders.append('Authorization', 'Bearer ' + token);
    httpHeaders.append('Content-Type', 'application/json');
    return this.http.get<User>(API_USERS_URL, { headers: httpHeaders });
  })
).subscribe(user => console.log({user}));

Upvotes: 0

Related Questions