Typescript: Delay code execution until a function has completed running

I've encountered an issue with my code that involves calling a function. Here is the snippet of code in question:

this.getAllOptions(questionID);
console.log("++++++++++++++++++++++++++++++++");
console.log(this.result);

The task of this function is straightforward - it invokes a service, which then returns an array of objects. What I specifically require from this returned data is just the "item.Content," formatted as a string. Below is the relevant code snippet:

result: string;
getAllOptions(question_ID){

    this.result = "";

    this._service.getOptionsQuestion(question_ID)
        .subscribe( data => {
            data.forEach(item => {
            console.log(item.Content);
            this.result += item.Content;
            });
        });
}

However, a problem arises where the lines of code after invoking the "getAllOptions()" function are executed prematurely. I am seeking a way for those subsequent lines to wait until the function has completed execution.

Is there a solution to accomplish this?

Answer №1

Patience is key when waiting for data to arrive. As soon as the getOptionsQuestion function finishes executing, the observable it generates has not yet received any data, so the callback provided to the subscribe method remains inactive.

There are various strategies one can employ to wait for the data. Personally, I find the async/await syntax in Typescript to be my favored choice as it enhances code readability:

import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import * as rsx from 'rxjs'

class Test {
    // Declaration of a dummy service
    _service : {
        getOptionsQuestion(nr: number): rsx.Observable<Array<{Content : string }>>
    }

    result: string;
    async getAllOptions(question_ID: number){

        this.result = "";
		const data = await this._service.getOptionsQuestion(question_ID).toPromise()

        data.forEach(item => {
            console.log(item.Content);
            this.result += item.Content;
        });
    }
    async otherMethod (questionID : number){
        await this.getAllOptions(questionID);
        console.log("++++++++++++++++++++++++++++++++");
        console.log(this.result);
    }
} 

Answer №2

To solve the problem, one approach is to utilize a promise in the getAllOptions function.

result: string;

getAllOptions(question_ID): Promise<void>{
    let resolveRef;
    let rejectRef;

    //create a new promise. Save the resolve and reject reference
    let dataPromise: Promise<void> = new Promise((resolve, reject) => {
        resolveRef = resolve;
        rejectRef = reject;
    });
    this.result = "";

    this._service.getOptionsQuestion(question_ID)
        .subscribe( (data: any) => {
            data.forEach(item => {
            console.log(item.Content);
            this.result += item.Content;
            });
            // resolve the promise once result is populated
            resolveRef(null);
        });

    //return promise created.
    return dataPromise;
}


// execute the console logs on then part of the promise returned by getAllOptions
this.getAllOptions(questionID).then(() => {
    console.log("++++++++++++++++++++++++++++++++");
    console.log(this.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

Struggling to assign the correct data type to a property in Typescript

I am encountering a TypeScript error with the following code. In this interface, the 'items' property can be either an object or an array depending on the code and response. I am unsure how to specify the datatype of 'array/object/any', ...

The key is not applicable for indexing the type as expected

Here is the TS code I am working with: type Fruit = { kind: "apple" } | { kind: "grape"; color: "green" | "black" }; type FruitTaste<TFruit extends Fruit> = TFruit["kind"] extends "apple" ? "good" : TFruit["color"] extends "green" ? "good" : ...

What is the method for implementing an Inset FAB with Material UI in a React project?

Currently, I am working on a project that requires an "Inset Fab" button to be placed between containers. After referencing the Material Design documentation, I discovered that the component is officially named "Inset FAB". While I was able to find some tu ...

Error: Trying to access the 'keyboard' property of an undefined object

I am encountering an error message 'Cannot read property 'keyboard' of undefined' and I'm not sure how to fix it. I just want to check if the keyboard is visible on the screen, but this specific line of code seems to be causing the ...

The dependencies of Nest are unable to be resolved by the system

Attempting to implement AuthService within UsersService and UsersService within AuthService results in a "circular dependency" issue. The error message states that "Nest can't resolve dependencies of the AuthService (UserModel, JwtService, ?). Please ...

What is the process of creating a new array by grouping data from an existing array based on their respective IDs?

Here is the initial array object that I have: const data = [ { "order_id":"ORDCUTHIUJ", "branch_code":"MVPA", "total_amt":199500, "product_details":[ { ...

Verify if a given string exists within a defined ENUM in typescript

I have an enum called "Languages" with different language codes such as nl, fr, en, and de. export enum Languages { nl = 1, fr = 2, en = 3, de = 4 } Additionally, I have a constant variable named "language" assigned the value 'de'. My g ...

Exploring the process of selecting checkboxes in Angular 6

I'm currently learning Angular 6 and I have a requirement to mark checkboxes based on specific IDs from two arrays: this.skillArray = [ {ID: 1, name: "Diving"}, {ID: 2, name: "Firefighting"}, {ID: 3, name: "Treatment"}, ...

Validator in Angular FormControl ensures that two fields have the same value or both are empty

When filling out a form with four fields, I have encountered a specific requirement. Two of the fields are mandatory, which is straightforward. However, the other two must either both be empty or both have a value - essentially resembling an XNOR logic sta ...

What is the process of extracting multiple attributes from an object that has been selected by a user using mat-options (dropdown list) in Angular?

Summary: A dropdown list contains objects, unsure how to capture multiple attributes of selected object. Current Implementation: I have successfully created a dropdown list that displays the details of an object retrieved through an API call: <mat-f ...

Obtain a string of characters from different words

I have been trying to come up with a unique code based on the input provided. Input = "ABC DEF GHI" The generated code would look like, "ADG" (first letter of each word) and if that is taken, then "ABDG" (first two letters o ...

Can JSON Web Tokens be utilized in a browser environment?

Searching for a way to parse the JWT token led me to this jsonwebtoken library https://www.npmjs.com/package/jsonwebtoken. It appears to be tailored for NodeJS. Is it feasible to utilize this library in the browser? My attempts so far have resulted in the ...

Using the --prod flag in Ionic 3 app on Android 7 results in the Keyboard not being displayed

After running the command ionic cordova run android --device, everything functions properly. However, when attempting the same command with the --prod flag, the input click fails to display the keyboard despite implementing the (onFocus) attribute in the & ...

Issue: Catching errors in proxy function calls

I am currently using Vue 3 along with the latest Quasar Framework. To simplify my API calls, I created an Api class as a wrapper for Axios with various methods such as get, post, etc. Now, I need to intercept these method calls. In order to achieve this ...

Reduce the size of a container element without using jquery

In my Angular application, I have structured the header as follows: -- Header -- -- Sub header -- -- Search Box -- -- Create and Search Button -- -- Scroll Div -- HTML: <h1> Header </h1> <h3> Sub header </h3> <div class="s ...

Ways to develop a dynamic Promise-returning Function

I find myself in a situation where I am aware of the type of data that will be returned when making a request to an API. Here is the function I have: const fetchData = async (url: string, options?: Object): Promise<any> => { const res = await f ...

Bringing in TypeScript declarations for the compiled JavaScript librarybundle

I have a custom library written in TypeScript with multiple files and an index.ts file that handles all the exports. To consolidate the library, I used webpack to compile it into a single index.js file but now I'm facing challenges importing it with ...

Do Not Activate the Android App with Deeplink in Ionic3

I'm currently using the ionic-plugin-deeplinks to enable deep linking within my app. Here are the steps I followed: $ ionic cordova plugin add ionic-plugin-deeplinks --variable URL_SCHEME=myapp --variable DEEPLINK_SCHEME=https --variable DEEPLINK_HOS ...

Learn the process of typing a property that will be displayed as a dynamic HTML element component

Looking for a way to render an HTML element dynamically based on a prop in a React component? interface ButtonProps { children: ReactNode; className?: string; as?: string; <--- ? [key: string]: unknown; } const Button = forwardRef({ children, ...

Translate array into object with correct data types (type-specific method)

Welcome In our project, we have implemented attributes support where each attribute acts as a class. These attributes include information on type, optionality, and name. Instead of creating an interface for every entity, my goal is to automate this proces ...