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

Debugging Typescript code with line numbers

When opening the console in a browser, typically the javascript line number of a function call or error message is displayed. However, my current setup involves using TypeScript, which gets compiled to Javascript. I am wondering if there is a way to retr ...

Is it possible to initiate an animation in a child component using an input variable?

I have a specific animation that I would like to trigger once an *ngFor loop completes ngAfterViewInit(): void { this.items.changes.subscribe(() =>{ Promise.resolve().then(() => { this.everythingLoaded(); }) }) } After the loop fini ...

Error: Unable to access the 'myDate' property as it is not defined

I've been working on a simple code, but I keep encountering a browser error. The expressjs logs also show an error message. TypeError: Cannot read property 'myDate' of undefined at getReportTable (XXX\dist\controllers&bsol ...

The URL for my JSON file cannot be located on my Angular server

Hey there! I'm currently working on setting up a server that will be pulling product data from a JSON file using HTTP. However, I've encountered an issue during the application build process where this error message pops up: Failed to load resou ...

Develop a JSON parsing function for VUE reusability

Currently, I am iterating through an array in Vue that contains objects with strings nested within. These objects have various properties such as idType, type, user, visibility, seller, product, company, and additionalData. notifications: [ 0: { idTy ...

An unhandled promise rejection occurred because no routes could be found to match. URL Segment:

I'm facing an issue with my application where it doesn't recognize the route even though I have defined and imported it in app.module. Whenever I try to redirect to a specific route upon data retrieval, I encounter this exception: onSubmit(){ ...

Experiencing Typescript errors solely when running on GitHub Actions

I've been working on a React+Vite project with the Dockerfile below. Everything runs smoothly when I execute it locally, but I encounter errors like Cannot find module '@/components/ui/Button' or its corresponding type declarations and error ...

How does the call method on array.prototype.includes work with arguments x and y?

Curious about the functionality of array.prototype.includes.call(x, y);. Discovered that includes() confirms if an array has the specified value and provides a true or false result. Learned that call() invokes this alongside any optional arguments. The ...

Error: The function was expecting a mapDiv with the type of Element, but instead undefined was passed - google

I have a map within a div tagged with #mapa. Whenever I try to plot a route on the map, it refreshes. I don't want the map to refresh, and here is the code I currently have: <div style="height: 500px; width: auto;" #mapa> <google-map heigh ...

"Curious why the change event doesn't trigger when selecting an option that is already selected

Angular reactive forms are causing an issue where the change method for select field does not fire when selecting an already selected option. You can view an example of this behavior at the following link: https://stackblitz.com/edit/angular-2e1cvz. In t ...

Facing challenges with parsing JSON files in an Angular 2+ application

Utilizing the Angular CLI, I have configured this project with the standard folder layout. My goal is to practice reading a JSON file from src/app/assets/items.json and then using it to display these items in the HTML. items.json: { "results": [ ...

Assigning a value and specifying the selected attribute for an options tag

Trying to understand the challenge of setting both a value and a selected attribute on an options tag. Each one works independently, but not together. For example: <select> <option *ngFor="let item of items" selected [ngValue]="item"> ...

Deactivate the button permanently upon a single click

In the project I'm working on, there is a verification page for e-mail addresses. When new users register, they are sent an e-mail with a link to verify their e-mail. If the link is not clicked within a certain time frame, a button appears on the page ...

Error: The Turborepo package restricts the use of import statements outside of modules

I created a typescript "test" package in turborepo, which imports and exports typescript functions. Due to being in turborepo, it gets copied to node_modules/test. When attempting to run import {func} from "test", an error is thrown: SyntaxError: Cannot ...

I'm currently facing a hurdle with this error, even though I've diligently followed all the necessary steps to deploy my Angular app on Her

An error occurred: Unable to access property 'Minus' of undefined. For more details, please refer to "/tmp/ng-9JMDN2/angular-errors.log". npm encountered the following errors while attempting to run scripts: ELIFECYCLE spawn file sh errno ENOENT ...

A step-by-step guide on retrieving the present date and time using TypeScript

Details This is my first time creating a VSCode extension using TypeScript, and I am having trouble displaying the current date/time in an information message. My Attempts I have searched through VSCode key bindings for any references to date/time, as w ...

Setting angular variables by assigning form values

My current reactive form setup looks like this: this.editform = new FormGroup({ 'username' : new FormControl(null,[Validators.required]), 'password' : new FormControl(null,[Validators.required]), 'full_name' : ne ...

I am experiencing an issue with the ng template binding when trying to use a button

The tolTemplate is not properly binding with the [tooltip] code snippet. <ng-template #tolTemplate> Just another: </ng-template> <button type="button" class="btn btn-success" [tooltip]="tolTemplate"> Show me tooltip with html </b ...

Obtaining data from a cookie or service within the app-routing module

My angular site, www.domainname.com, utilizes an app-routing module with the following Routes: const routes: Routes = [ { path: "homepage/:lang/:country", ... }, ... { path: "**", redirectTo: "/homepage/en/gb", pathMatch: "fu ...

Solving the problem of cookieParser implementation in NestJS

Greetings! I have a question for you. Currently, I am working on developing a backend using NestJS, a Node.js framework. Everything is functioning smoothly except for some issues when it comes to hosting. I have created a new NestJS project and made some ...