Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I'm building an observable data service based on the following article: https://coryrylan.com/blog/angular-2-observable-data-services

In the article he used an array as an example, here I will use the user object since I'm developing the user service.

Here's what I got:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Events, SqlStorage, Storage } from 'ionic-angular';
import { Subject } from 'rxjs/Subject';


export interface DataStore {
  user: Object
}

@Injectable()
export class UserService {

  private baseUrl: string;
  private storage: Storage;
  private _user$: Subject<Object>;
  private dataStore: DataStore;

  constructor(
    private http: Http
  ) {
    this.baseUrl = 'http://localhost:3000';
    this.storage = new Storage(SqlStorage);
    this._user$ = <Subject<Object>>new Subject();
    this.dataStore = {
      user: { name: '' }
    };
  }

  set user$(user: Object) {
    this.storage.set('user', JSON.stringify(user));
    this.dataStore.user = user;
    this._user$.next(this.dataStore.user);
  }

  get user$() {
    return this._user$.asObservable();
  }

  loadUser() {
    return this.storage.get('user').then(
      ((user: string): Object => {
        this.dataStore.user = JSON.parse(user);
        this._user$.next(this.dataStore.user);
        return this.dataStore.user;
      })
    );
  }

  login(accessToken: string) {
    return this.http
      .post('http://localhost:3000/login', { access_token: accessToken })
      .retry(2)
      .map((res: Response): any => res.json());
  }

  logout(): void {
    this.storage.remove('user');
  }

}

To authenticate I call the login() function and set the user data if everything ok.

this.userService.login(this.data.accessToken)
  .subscribe(
    (user: Object) => {
      this.userService.user$ = user;
      this.nav.setRoot(EventListComponent);
    },
    (error: Object) => console.log(error)
  );

I feel it is better set the user data inside the service. I could do the following:

login(accessToken: string) {
  return this.http
    .post('http://localhost:3000/login', {
      access_token: accessToken
    })
    .retry(2)
    .map((res: Response): any => res.json())
    .subscribe(
      (user: Object) => {
        this.userService.user$ = user;
        this.nav.setRoot(EventListComponent);
      },
      (error: Object) => console.log(error)
    );
}

But I won't be able to subscribe to the login() function in the component since it's already subscribed. How could I redirect the user if everything ok or show an alert if anything goes wrong in the component but setting the user inside the service?

In the main component I load the user data and set the rootPage:

this.userService.loadUser().then(
  (user: Object) => this.rootPage = EventListComponent,
  (error: Object) => this.rootPage = LoginComponent
);

I thought that calling the loadUser() function at this time I would not have to call it again, but I have to call it in all components that I need the user data:

this.user = this.userService.user$;
this.userService.loadUser();

I don't think the service is the way it should, what could I improve? Is there any better way to achieve what I want? Any example or idea?

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.