0

I'm learning Observables and trying to implement a service for login validation. Dummy data is like this

export class Users {
  public users: IUser[] = [];

  constructor() {
    this.users = [
      new IUser({ username: "protagonist", password: "hello123" }),
      new IUser({ username: "rono67", password: "!@vioped" }),
      new IUser({ username: "donaldtrump", password: "melenia@34" })          
    ];
  }

and structure of IUser is like this.

export class IUser {
    usename:string;
    password:string;
}

I'm passing the entered username and password to the service class and I want to have an observable call which traverse through the dummy data and if it finds the matching credentials, it shall return it. I do not want to make any HTTP call. Method is something like this-

 validLogin(accountInfo: IUser): Observable<IUser> {
        return ---------
          .map((user:IUser) => user.filter((user:IUser) => user.usernanme == accountInfo.username && user.password == accountInfo.password);
      }

I'm not sure what piece of code needs to be written in the place of return ------. All of the results which I got in the web are implementing "return this.http.post"

Is it possible to apply RxJs on mock data? Kindly suggest.

Mark van Straten
  • 9,287
  • 3
  • 38
  • 57
Protagonist
  • 1,649
  • 7
  • 34
  • 56
  • 2
    `Observable.of(...)`? Or you could use the [in-memory web API](https://github.com/angular/in-memory-web-api) and practice against something a little more realistic. – jonrsharpe Jul 08 '17 at 08:54
  • Possible duplicate of [Angular2: convert array to Observable](https://stackoverflow.com/questions/35527500/angular2-convert-array-to-observable) – jonrsharpe Jul 08 '17 at 10:38

2 Answers2

1

You can use Observable.of or Observable.from to create an Observable object from anything. Since, you want to do some operation on IUser array, I suggest you use Observable.of

Here what it would look like

export class Users {
   public users: IUser[] = [];
   _users: Observable<IUser[]>;

   constructor() {
      let users = [
      // your dummy data
      ];

      for (let user of users) {
          this.users.push(new IUser(user));
      }
      this._users = Observable.of(this.users);
  }

   validLogin(accountInfo: IUser): Observable<IUser> {
    return this._users.map((user:IUser) => 
           user.filter((user:IUser) => user.usernanme == accountInfo.username && user.password == accountInfo.password);
   }

}
Bunyamin Coskuner
  • 8,719
  • 1
  • 28
  • 48
  • Hi, I'm getting the below error "Observable' is not assignable to type 'Observable'. Type 'IUser' is not assignable to type 'IUser[]'. Property 'length' is missing in type 'IUser" – Protagonist Jul 08 '17 at 10:20
  • 1
    `Observable.from` will make an observable stream of each individual user, not of the whole array as the OP wants – jonrsharpe Jul 08 '17 at 10:21
  • @jonrsharpe I'm restricted to use only observable :( – Protagonist Jul 08 '17 at 10:34
  • @Protagonist 1. Why? 2. Why not mention that? 3. That comment suggests something that does use only observable, and is also mentioned in this answer (and the documentation, and that dupe). – jonrsharpe Jul 08 '17 at 10:38
  • Well actually yeah my mistake. You should use `Observable.of` since you want to use the whole array and do some filtering. I edited my answer. Thanks for pointing it out @jonrsharpe – Bunyamin Coskuner Jul 08 '17 at 10:42
0

Since your Users class is already a mock implementation (containing all users directly in an array) you can just wrap the array into an Observable and filter based on user&pwd to return the first result:

validLogin(accountInfo: IUser): Observable<IUser> {
  return Rx.Observable.from(users)
    .filter(dbUser => dbUser.username == accountInfo.username && dbUser.password == accountInfo.password)
    .take(1);//no user found => observable completes without data
}

Depending on the current implementation you might not want to return an empty Observable if no user was found with the correct credentials but an Error, that is up to you.

Mark van Straten
  • 9,287
  • 3
  • 38
  • 57