Multiple asynchronous calls in Angular 2

In my Component, there is a function that is supposed to return a value (Promise). This value requires information from two distinct sources: an API call and data from a database.

The method in question looks like this:

public getValue(): Promise<number> {

    return this.dataProvider.loadData().toPromise().then(data => {
        return data.feePerc
    }).then(feePerc => {
        let url = `${apiUrl}/mycontroller/value`            
        return new Promise<number>(resolve => {                
            return this.http.get(url)
                .map(response => {                       
                    let value = response.json()
                    return resolve(value * (1 + (feePerc / 100)))
                })
        })
    })
}

However, the function does not work as intended. While the feePerc value is returned successfully, using http.get within a Promise seems to be causing issues. The map() function is never executed.

I initially thought about handling these asynchronous functions simultaneously and synchronizing their results before returning the final outcome. Despite struggling with an elegant solution using promises, I have yet to figure out a proper chained approach.

package.json:

  • "@angular/core": "4.2.5",
  • "rxjs": "5.4.2",

Answer №1

map() is not being utilized as you never subscribe to the observable.

Your use of promises in this scenario is considered an antipattern, and it's worth noting that there shouldn't be a need for promises when working with observables, as they offer built-in mechanisms for chaining operations.

(By the way, it's rather unusual to apply toPromise() in the initial call, which is the correct method to convert an observable to a promise, but then not use it in the subsequent call.)

The following code snippet demonstrates the proper approach:

public getValue(): Observable<number> {
    const url = `${apiUrl}/mycontroller/value`;

    return this.dataProvider.loadData()
      .map(data => data.feePerc)
      .switchMap(feePerc => 
        this.http.get(url).map(response => response.json() * (1 + (feePerc / 100))));
}

Please take into account that Angular 2 has been around for nearly two years now, with the current version being 6.x. It's advisable to consider upgrading, particularly transitioning to RxJS 6 and HttpClient among other enhancements.

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 are the methods used in TypeScript to implement features that are not available in JavaScript, despite TypeScript ultimately being compiled to JavaScript?

After transitioning from JavaScript to TypeScript, I discovered that TypeScript offers many features not found in JS, such as types. However, TypeScript is ultimately compiled down to JavaScript. How is it possible for a language like TypeScript to achie ...

Obtain the default/initial argument type of typescript for extension purposes

Currently, I am in the process of developing code that automatically generates type hints based on function calls related to GraphQL Nexus tasks. In one of its functions, it requires an anonymous type constructed from the attributes generated automaticall ...

Hold off on making any promises regarding Angular 2

Let me start by stating that I have gone through many responses and I am aware that blocking a thread while waiting for a response is not ideal. However, the issue I am facing is quite complex and not as straightforward to resolve. In my advanced project, ...

Enumerated types in Typescript: access the values

Below is a flagged enum I have: enum PermissionEnum { SU = 1 << 0, // 1 Administrator = 1 << 1, // 2 User = 1 << 2 // 4 } If the value given is 6, how can I achieve: An array of strings -> ['Adm ...

Notification of an uncaught promise being rejected

After creating this function, I keep encountering the Unhandled Promise Rejection Warning. Despite my attempts to refactor it, I just can't seem to get it right. router.post('/authenticate', function (req, res) { User.findOne({username: req ...

What is the method to utilize global mixin methods within a TypeScript Vue component?

I am currently developing a Vue application using TypeScript. I have created a mixin (which can be found in global.mixin.js) and registered it using Vue.mixin() (as shown in main.ts). Content of global.mixin.js: import { mathHttp, engHttp } from '@/ ...

Redux ConnectedProps will always have a type of never

I am facing an issue while attempting to connect a component to my Redux store following the steps outlined in the official documentation guide. The props that are connected seem to be coming through as type never. Here is a snippet of my code: Type defi ...

The index signature for strings appears to be duplicated in this TypeScript file, causing an

I am attempting to create a type with an index signature in TypeScript. Here is the code snippet: export interface LoginState { account: { [userName: string]: string; [password: string]: string; }; } However, I ...

Exploring the various methods of setting up a Create React App project with TypeScript

One of my old books from a year ago mentioned... npx create-react-app XXX --typescript But looking at the current Create React App documentation, it says... npx create-react-app XXX --template typescript They both seem to yield the same result. Is ther ...

Require assistance with Dhtmlx and Wijmo grid context menus, as well as touch events, specifically when utilized on an iPhone's Safari browser

I recently created a web application utilizing DHTMLX 5.0 and Wijmo grid. Everything functions smoothly when accessed on Chrome for Android, including the context menu which is opened with a touch-'press and hold' gesture. However, I have encount ...

What is the best way to capture the inputs' values and store them accurately in my object within localStorage?

Is there a more efficient way to get all the input values ​​and place them in the appropriate location in my object (localStorage) without having to individually retrieve them as shown in the code below? Below is the function I currently use to update ...

Tips on including a trash can symbol to rows in a bootstrap table using React

I am working on a table that contains various fields, and I want to add a trash icon to each row so that when it is clicked, the specific row is deleted. However, I am encountering an issue where the trash icon is not showing up on the row and I am unable ...

What is the best way to incorporate additional properties while utilizing useSession in Next.js with TypeScript?

I've encountered an issue while trying to add new properties using useSession() in a TypeScript environment. Although it works on console.log, there is an error related to the type mismatch. The useSession() function typically returns name, email, an ...

Is it possible to export all types/interfaces from .d.ts files within multiple folders using index.ts in a React TypeScript project?

In my current React project, I am managing multiple configuration folders: -config -api/ |index.ts |types.d.ts -routes/ |index.ts |types.d.ts ... For example, in the api/index.ts file, I can import necessary types using import {SomeTyp ...

The function ValueChange remains uninvoked

Query: The issue is that valueChanges is only triggered for the entire form and not for specific controllers. Although this approach works, it returns the complete object. public ngOnInit(): void { this.form.createWagonBodyForm(); ...

The error "Cannot access property afs (Angularfirestore) of undefined in the collection.set()" occurred

In the current code snippet below, I am iterating over a collection of data and updating a field if the email matches. The issue arises when trying to set new values where it crashes. The iteration process itself functions correctly, with afs being Angular ...

Switch app engines in real-time based on the URL path with express framework

How can I dynamically set App Engine based on the URL? In my application, I have two render engines available: serverSideRenderEngine & browserRenderEngine If the URL is /home, the app.engine should be set as serverSideRenderEngine If the URL is /l ...

A TypeScript method for accessing deeply nested properties within an object

I'm currently working on a function that utilizes typings to extract values from a nested object. With the help of this post, I managed to set up the typing for two levels successfully. However, when I introduce a third (known) level between the exis ...

Issue encountered in TypeScript: Property 'counter' is not found in the specified type '{}'.ts

Hey there, I'm currently facing an issue while trying to convert a working JavaScript example to TypeScript (tsx). The error message I keep encountering is: Property 'counter' does not exist on type '{}'.ts at several locations wh ...

Learn how to reposition the mat-option easily

I have an angular app with an autocomplete field that I need to adjust the position of. I have consulted the official documentation under the method updatePosition, which states: "Updates the position of the autocomplete suggestion panel to ensure that it ...