Angular - reusing an observable for different queries
There's nothing (obviously) wrong with your code. You deal with observables the efficient way, IMO. Cache is good. The fact you're constructing a "base" observable in constructor without subscribing to it there is good as well...

There are only a few things I can point out:


Design: Be careful with caching, if your user information changes often, the cache may bite you back. You may want to implement some kind of cache invalidation policy.
Design: If your system has thousands of users, you may want to not load all of them into memory at once. That would require your API support pagination though. If the users are few, it's totally okay to do what you're doing, I think.
RxJs: not sure why pipe() and tap() are used the way are used. I think, it's easier to use do() and map() as shown in the code below. Chaining looks much more readable (as "step-by-step" explanation of how the data is transformed into the desired result).
Idioms: TypeScript is all about types. Do specify a known type when possible instead of using any. E.g. Observable&lt;IUserDetails[]&gt; is better than Observable&lt;any[]&gt;.
Style: Variable naming is important. Do not use one-letter names (u), they are pure evil. Names like data are also evil, in your case it's better to call it response. The resource$ can probably be nicer to the reader if called userDetails$. You get the idea.




@Injectable()
export class UsersApiService {

  private readonly baseUrl: string = 'https://reqres.in/api/users';
  userDetails$: Observable&lt;IUserDetails[]&gt;;

  constructor(private http: HttpClient) {
    this.userDetails$ = this.http
      .get&lt;IUserDetails[]&gt;(this.baseUrl)
      .do(response =&gt; console.log('"getUsers" successfully called!'))
      .map(response =&gt; response.data)
      .publishReplay(1)
      .refCount();
  }

  getUsers(): Observable&lt;IUser[]&gt; {
    return this.userDetails$
      .map(userDetailsList =&gt;
        userDetailsList.map(userDetails =&gt;
          &lt;IUser&gt;{ id: userDetails.id, name: `${userDetails.first_name} ${userDetails.last_name}` }
        )
      );
  }

  getUserById(id: number): Observable&lt;IUserDetails&gt; {
    return this.userDetails$
      .map(userDetailsList =&gt; &lt;IUserDetails&gt;userDetailsList.find(userDetails =&gt; userDetails.id === id));
  }
}