Angular 5 and the benefits of concurrent requests

My goal is to execute multiple requests in parallel, fetch the results, and combine them. To achieve this, I have implemented the following function:

    getStudent(query): Observable<any> {
    const code = this.http.get(
        `http://localhost:8090/etudiantFiltre?codEtudiant=${query}`
    );
    const prenom = this.http.get(
        `http://localhost:8090/etudiantFiltre?prenom1=${query}`
    );
    const nom = this.http.get(
        `http://localhost:8090/etudiantFiltre?patronyme=${query}`
    );
    return Observable.forkJoin([code, nom, prenom]).map(responses => {
        console.log(`code : ${code}
                     nom : ${nom}
                     prenom : ${prenom}`);
        return [].concat(...responses);
    });
}

While this function works fine for single-word queries like 'John', I needed to enhance it to support queries with spaces. To address this, I modified the function to split the query by spaces and then call the original method on each element. I then used the merge method to combine the results.

getAllStudent(query) {
    const studentObservable: Observable<Response>[] = [];
    query.split(' ').forEach(element => {
        studentObservable.push(this.getStudent(element));
    });
    return Observable.merge(studentObservable);
}

For making the actual method call, I have the following in my ngOnInit:

    ngOnInit() {
    this.getAllStudent('name firstname').subscribe(data => {
        this.st = data;
    });
}

However, when I try to print the result of the method, I'm getting unexpected output and I'm unsure why:

{
    "_isScalar": false,
    "source": {
    "_isScalar": false,
    "sources": [
        {
        "_isScalar": false,
        "source": {
            "_isScalar": false,
            "source": {
            "_isScalar": false,
            "source": {
                "_isScalar": true,
                "value": {
                "url": "http://localhost:8090/etudiantFiltre?codEtudiant=firstname",
                "body": null,
                "reportProgress": false,
                "withCredentials": false,
                "responseType": "json",
                "method": "GET",
                "headers": {
                    "normalizedNames": {},
                    "lazyUpdate": null,
                    "headers": {}
                    ...

Answer №1

If you wish to consolidate multiple requests using forkJoin and combine them together, you can utilize combineLatest. For a streamlined final observable output, consider implementing mergeMap which can process an array of responses and return a simplified response array.

const keywords = ['yanis','git'];
const request$ = [];

keywords.forEach((keyword) => {
        //Create an array of ForkJoin Observables.
        request$.push(forkJoin([
            this.http.get('https://randomuser.me/api/?query='+keyword),
            this.http.get('https://randomuser.me/api/?query='+keyword),
            this.http.get('https://randomuser.me/api/?query='+keyword)
        ]));
});
// Combine all requests and apply the mergeMap strategy.
Observable.combineLatest(request$).mergeMap(e => {
    //Merge all results into a single returned array. Can also handle deduplication.
    const returned = [];
    e.forEach(t => {
        t.forEach(i => returned.push(i));
    });
    return returned;

}).subscribe(e => {
    //Each result returned by mergeMap will be received here.
    console.log(e);
});

Check out the online example: https://stackblitz.com/edit/angular-66ic6c?file=app%2Fapp.component.ts

Answer №2

If you're looking to make multiple requests in parallel, consider using the forkJoin function with studentObservables. Another option to consider for a more elegant solution is to use map instead of forEach.

fetchStudents(query) {
    let studentObservables = query.split(' ')
        .map(term => this.retrieveStudent(term));
    return Observable.forkJoin(studentObservables);
}

ngOnInit() {
    this.fetchStudents('studentName studentSurname')
        .subscribe(result => console.log(result));
}

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

What could cause a member variable to be uninitialized in the ngInit method in Ionic/Angular, even though it was initially set in the constructor

Despite setting the modal form to be bound to an instance of "Foo" during its construction, I encountered a strange issue where, post-constructor, this.foo became undefined. Even after verifying this through breakpoints and console.log, the problem persist ...

Missing expected property in TypeScript casting operation

I recently came across this intriguing playground example outlining a scenario where I attempted to convert an object literal into an object with specific properties, but encountered unexpected results. class X { y: string; get hi(): string { ...

TypeScript: Defining an Array Type within a Namespace or Module

Within a specific namespace, I have the following code: const operation1 = Symbol("operation1"); const operation2 = Symbol("operation2"); export interface Array<T> extends IConjable<T>, ISeqable<T> {} Array.prototype[op ...

Angular 9 - Auto-adjust the height of the text box as the user types, returning to its original size when no longer in focus

I need a solution where an input field's height adjusts to display the user's entry, then returns to normal size when they click away. It should function similar to this example image: https://i.stack.imgur.com/yKcik.png Once the user enters th ...

The power of Ionic 2 combined with the Web Audio API

I am currently developing an Ionic 2 application that requires access to the user's microphone. When working on a web platform, I would typically use the following code snippet to obtain microphone access. navigator.getUserMedia = (navigator['ge ...

Best practice for integrating Typescript into an established ASP.NET 4 Webforms project

Currently, I am working on an older asp.net 4.0 Webforms project using Visual Studio 2015. My goal is to transition from using Javascript to TypeScript for certain client side code tasks. While I have experience using TypeScript in projects outside of Vis ...

The ngmodel variable is not responding to dynamic changes

I'm currently working on dynamically changing a date and getting it to reflect in the view, but for some reason it's not showing up. When the date is hard-coded in an array like this, it works perfectly fine and shows up in the view. My date : Ar ...

Oops! The system encountered a problem: the property 'modalStack' is not recognized on the type 'NgxSmartModalService'. Maybe you meant to use '_modalStack' instead?

Currently, I'm facing an issue while attempting to run ng build --prod in my Angular 6 project. I have also incorporated the NgxSmartModal package for handling modals. Unfortunately, the build process is failing and I can't seem to figure out why ...

Firebase - Accessing data for a specific item

Apologies for the lengthy question. I have a collection of events that I retrieve like this: export class HomePageComponent implements OnInit { events: FirebaseListObservable<EventModel[]>; constructor( private authService: AuthService, ...

Creating a dynamic multi-line list in Ionic application is a breeze!

I'm a beginner in Ionic and I am interested in creating a Multi-line List similar to how we generate list-views in Android with custom views and using an Array of custom objects programmatically. Can Multi-line Lists be generated with data from an Ar ...

Adjustable angular-design sidebar with collapsible sections

My goal is to create a mat-drawer that can be resized and will collapse its content when it reaches a certain min-width. I've implemented this library to make the mat-drawer resizeable, which seems to be working well. The issue I'm encountering ...

Protecting a client's encryption key

I was given the task of enhancing the security of a website that utilizes Angular v15 + JWT. The first step was to alter the login POST-request (HTTPS) from this format: /api/login?username=user_name&password=pass123 to this format: /api/login?credent ...

Testing a subclass in Angular 6 using Karma and the @Input decorator

After finding no answers to related questions, I've decided to pose my own specific case regarding unit testing an Angular 6 component that is a subclass of a base component. The base component itself includes an @Input decorator and looks like this: ...

Issue encountered when attempting to deploy a node/express API with now.sh

Currently, I am in the process of deploying a node/express API with multiple endpoints on now.sh. I am seeking guidance on properly configuring the now.json file for this deployment. In order to provide a visual representation of my project's comple ...

Can you identify the specific syntax for a 'set' function in TypeScript?

I have a TypeScript function that looks like this: set parameter(value: string) { this._paremeter = value; } It works perfectly fine. For the sake of completeness, I tried to add a type that specifies this function does not return anything. I experimen ...

setting up angular 4 application on an IIS server

When running ng build --prod --base-href=/my folder/subfolder/, I also made sure to copy the dist folder into the specified subfolder. After setting the physical path in IIS, I tried to browse the site but only encountered a blank screen with no error mes ...

Restricting a generic parameter to a combination type in Typescript

Is there a method in Typescript to restrict a generic parameter to only accept a union type? To clarify my question, I wish that T extends UnionType would serve this purpose: function doSomethingWithUnion<T extends UnionType>(val: T) {} doSomethingW ...

Retrieving Headers from a POST Response

Currently, I am utilizing http.post to make a call to a .NET Core Web API. One issue I am facing is the need to extract a specific header value from the HTTP response object - specifically, the bearer token. Is there a method that allows me to achieve thi ...

How can I enable SCSS/SASS support on Parcel-Angular5?

I started a project using angular cli. My intention is to incorporate scss into the project. In the terminal of WebStorm, I entered : ng set defaults.styleExt scss I proceeded by renaming all the .css files to .scss and adjusted the imports accordingly ...

Save data to local storage when the form is submitted, retrieve it when the page is reloaded

I need help with setting form data in local storage upon form submission and displaying a message in the console if the form has already been submitted when the page is refreshed. I am struggling to write the reload condition for this functionality. Here ...