On my Angular2 projects i used to create a service to care about the system authentication, and on this service i store the user data on an observable.
I want to avoid to repeatedly create a local variable and subscribe to this observable in every single component that needs to use or manipulate the user data stored on the service.
Can i simplify the access to this information in a pretty way?
export class AuthenticationService {
private readonly api_url: string = environment.API_URL;
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;
constructor(private http: HttpClient) {
// Get data from local storage in case the page refreshes
let obj = JSON.parse(localStorage.getItem('auth'));
this.currentUserSubject = new BehaviorSubject<User>(obj ? obj.user : null);
this.currentUser = this.currentUserSubject.asObservable();
}
login(username: string, password: string) {
let _this = this;
return this.http.post<any>(this.api_url + 'login/', { "username": username, "password": password }).pipe(map(response => {
// login successful if there's a user and a token in the response
if (response.user && response.token) {
// store user details in local storage to keep user logged in between page refreshes
localStorage.setItem('auth', JSON.stringify(response));
this.currentUserSubject.next(response.user);
}
return response;
}));
}
logout(): void {
localStorage.removeItem('auth');
this.currentUserSubject.next(null);
}
}
This is what i want to avoid to do on all components that need access to the data:
export class LoginComponent implements OnInit {
currentUser: User;
ngOnInit() { }
constructor(
private authenticationService: AuthenticationService) {
this.authenticationService.currentUser.subscribe(user => {
this.currentUser = user;
});
}
}
you still have to subscribe but you can use rxjs and either a behavior subject or subject - so that way when you call the instance easily and bind only to the variable you want through the object that is passed to you, behavior subjects also work with arrays. one cannot really escape using service binding, but one can make it cleaner and do it once vs, every component.
the other way would be to do input binding but there are limitations to how much data one can inject into a component and it allows you to use take(1) etc...
fake interface
subject as observable
from this point forward you only have to subscribe or send to a promise
.