The method takes in an array of user names along with an HTTP request for each, then it will generate an observable array of user objects as output

I need to retrieve an array of user objects from a non-observable array of usernames (string[]). I am looking for a method that can fetch each user object through getUser(username) (HTTP GET request from Angular in-memory web API) for each provided username string, and then ultimately return an observable array of user objects. However, I am facing challenges figuring this out despite trying different approaches.

My preference is to avoid using promises if possible.

Here is the current method attempted:

usernamesToUserObjects(usernames: string[]): User[] {
  var members: User[] = [];

  for (let username of usernames) {
    if (username.trim() === '') {
      continue;
    } else {
      this.userService.getUser(username.trim())
       .pipe(
          map((user: User[] | undefined) => {
            if (user !== undefined) {
              console.log(`(debug) ${user.username} was found!`);
              members.push(user);
            }
          })
        );
    }
  }

  // I acknowledge that the requests are not completing before moving on to the next one, but I need assistance in resolving this issue
  console.log(`(debug) User objects are : ${members}`);
  return members;
}

UserService methods in use: (functioning correctly)

usersUrl = '/api/users';

constructor(private http: HttpClient) {}

// fetching users in this manner in order to retrieve them from the Angular web api (can only be retrieved by 'id' and not by 'username')
users = this.http
  .get<IUser[]>(this.usersUrl)
  .pipe(retry(2), catchError(this.handleError('getUsers()', [])));

// check if user exists in the list of users
getUser(username: string): Observable<IUser | undefined> {
  return this.users.pipe(
    take(1),
    map((users: IUser[]) => {
      return users.find((user) => user.username === username);
    })
  );
}

How can I return an Observable<User[]> and then extract User[] from that observable?

Answer №1

The reason the function can't simply return a `User[]` is because fetching a single `User` appears to be an asynchronous task. In this case, it's recommended to either return a `Promise` or an `Observable`. The better option here would be to go with the `Observable` approach.

To handle all Observables in a synchronous manner, one solution is to utilize forkJoin, which serves as the equivalent of Promise.all().

usernamesToUserObjects(usernames: string[]): Observable<User[]> {
  return forkJoin(
    usernames
      .filter(username => username.trim() !== '')
      .map(username => this.userService.getUser(username.trim()))
  ).pipe(
    map(users => users.filter(user => user !== undefined))
  )
}

Interactive Playground

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The issue of HTTP parameters not being appended to the GET request was discovered

app.module.ts getHttpParams = () => { const httpParamsInstance = new HttpParams(); console.log(this.userForm.controls) Object.keys(this.userForm.controls).forEach(key => { console.log(this.userForm.get(key).value) const v ...

TypeScript: When using an API, it consistently returns an empty object with the type { [key: string]: any }

Every time I try to fetch data from the API, it always comes back empty. See example code snippet below: interface DataStore { [key: string]: any, } static GetData = async (req: Request, res: Response): Promise<Response> => { let obj: Dat ...

Issue with retrieving all phone numbers from a contact in Ionic

Hope you're doing well! I'm encountering an issue with Ionic Contacts. Currently, I'm able to retrieve all the contacts using my code but I need help extracting all the phone numbers associated with each contact. For example, if John has 3 ...

Transform object into JSON format

Is there a way to transform an object into JSON and display it on an HTML page? let userInfo = { firstName: "O", lastName: "K", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2b44476b445b05484446">[ema ...

Having difficulty accessing certain code in TypeScript TS

Struggling with a TypeScript if else code that is causing errors when trying to access it. The specific error message being displayed is: "Cannot read properties of undefined (reading 'setNewsProvider')" Code Snippet if (this.newsShow != ...

Currently, my goal is to upload a photo using Cloudinary's post API without relying on the Cloudinary SDK

Recently, I have been exploring the integration of cloudinary with Angular. In my quest to upload an image to cloudinary without using the SDK, I came across the option to do so via the post API. However, my attempts with the following code snippet were un ...

Angular Typescript Filter failing to connect with service injection

I am having trouble accessing the Constant app within a filter in Angular TypeScript. How can I successfully access a service inside a filter? Module App.Filter { import Shared = Core.Shared; export class MilestoneStatusFilter123 { static $inject = ...

Is it possible for changes made to an object in a child component to be reflected in the parent component

When passing an object to the child component using , how can we ensure that changes made to a specific property in the object within the child component are visible in the parent component? In my understanding, changes would not be reflected if we were p ...

Using Google OAuth2Client with Angular 4

I am encountering an issue while trying to verify the ID token for my client using Google's example. You can find the example code here. const {OAuth2Client} = require('google-auth-library'); // <-- facing issues here const client = new ...

What are some ways to conceal methods within a class so that they are not accessible outside of the constructor

I am a newcomer to classes and I have written the following code: class BoardTypeResponse { created_on: string; name: string; threads: string[]; updated_on: string; _id: string; delete_password: string; loading: BoardLoadingType; error: Bo ...

Utilize Ngrx to keep an eye on specific items within the store

If we consider an interface called INotification: export interface INotification { id: number; DateReceived: number; Title: string; Message: string; Tipology: string; isRead: number; } and a reducer system. In the component, it&ap ...

Issues with implementing Firebase Phone Authentication in Ionic 3

When trying to authenticate a phone number in Ionic 3 using Firebase, the program runs without error. However, after entering the phone number, nothing happens... The .html code is shown below: <ion-item> <ion-label stacked>Phone Number</i ...

Search input in real-time

I am in the process of implementing a live search input feature in Ionic 3 within a form group. Within my TypeScript file, I have the following code: getSubElements(selectedValue) { if(selectedValue){ this.VisitesProvider.getEcolesLi ...

Learn how to host a singular instance of an Angular application for every unique route, similar to the setup utilized in meet.jit.si

Is there a way to create an Angular app that loads a new instance of itself on every route/url? For example, visiting http://happy-app.com/happy would show the app in one state, and going to http://happy-app.com/happier would load the same app in a differe ...

How can you define the types of function arguments when destructuring arguments in TypeScript?

TS throws an error that states: Error:(8, 20) TS7031: Binding element 'on' implicitly has an 'any' type. Error:(8, 24) TS7031: Binding element 'children' implicitly has an 'any' type. Below is the function I am wor ...

angular primeng table has a checkbox to select all checkboxes

Is there a way to check all checkboxes in a table when the checkbox in the table header is clicked? I am currently utilizing angular 12 and primeNG table for this functionality. <p-table styleClass="text-sm" [value]="value" [loading] ...

ES5 approach to Angular2 HTTP Providers (not TypeScript)

I'm currently developing an application and experimenting with Angular2 using ES5 JavaScript for fun. My main inquiry right now is how to access the Http service. Most of the available documentation is in TypeScript, which is not very helpful, or it p ...

Approach to Global Components in Angular 2

What is the optimal method for ensuring a component is accessible globally, such as a login modal? Create a new instance in each component view Dynamically instantiate a new one when needed Declare it in the AppComponent, create a function to handle it ...

Having trouble with the ag-grid demo - grid not displaying as intended

Struggling to wrap my head around the "ag-grid" Typescript grid component for use in my Angular 6 applications. The website seems promising, but I am having trouble getting their "Getting Started" demo to function on my setup. I followed all the setup st ...

Differences between Angular TS Lint onInit and ngOnInit

My TS Lint issue warned me to implement the OnInit interface and included a link to this page: https://angular.io/docs/ts/latest/guide/style-guide.html#!#09-01 I'm curious, what sets apart `onInit` from `ngOnInit`? Both seem to work just fine for me. ...